在JavaScript / HTML中,转移字符导致js生成的html出错

举个例子:

javascript 复制代码
// 当song中存在英文单引号时,会导致无法正确处理:
p.innerHTML = `<li onclick="clicksong('${song}')">${song}</li>`;

这是一个典型的XSS漏洞和安全问题。当song变量包含单引号时,会破坏JavaScript字符串,导致语法错误或安全漏洞。以下是几种改进方案:

方案1:使用数据属性(推荐)

javascript 复制代码
p.innerHTML = `<li data-song="${escapeHTML(song)}">${escapeHTML(song)}</li>`;
p.querySelector('li').addEventListener('click', function() {
    clicksong(this.dataset.song);
});

方案2:使用事件委托

javascript 复制代码
p.innerHTML = `<li>${escapeHTML(song)}</li>`;
p.querySelector('li').addEventListener('click', () => {
    clicksong(song);
});

方案3:如果必须保持内联事件,使用JSON序列化

javascript 复制代码
p.innerHTML = `<li onclick="clicksong(${JSON.stringify(song)})">${escapeHTML(song)}</li>`;

完整的HTML转义函数

javascript 复制代码
function escapeHTML(str) {
    const div = document.createElement('div');
    div.textContent = str;
    return div.innerHTML;
}

// 或者使用更全面的转义
function escapeHTML(str) {
    return str.replace(/[&<>"']/g, function(match) {
        const escape = {
            '&': '&amp;',
            '<': '&lt;',
            '>': '&gt;',
            '"': '&quot;',
            "'": '&#39;'
        };
        return escape[match];
    });
}

方案4:使用模板引擎或框架

javascript 复制代码
// 使用现代JavaScript创建元素
const li = document.createElement('li');
li.textContent = song;
li.addEventListener('click', () => clicksong(song));
p.appendChild(li);

最佳实践示例

javascript 复制代码
// 安全的歌曲列表渲染函数
function renderSongList(songs, container) {
    const fragment = document.createDocumentFragment();
    
    songs.forEach(song => {
        const li = document.createElement('li');
        li.textContent = song;
        li.addEventListener('click', () => clicksong(song));
        fragment.appendChild(li);
    });
    
    container.innerHTML = ''; // 清空容器
    container.appendChild(fragment);
}

关键改进点

  1. 分离HTML和JavaScript:避免在HTML中嵌入JavaScript代码
  2. 正确转义:对动态内容进行适当的HTML转义
  3. 使用事件监听器 :代替内联的onclick属性
  4. 数据属性:安全地存储需要的数据

推荐使用方案1或方案4,它们完全避免了字符串拼接带来的安全问题,代码也更易维护。

相关推荐
揽星河..11 小时前
【C语言】结构体
c语言·开发语言
2601_9669496511 小时前
如何封装 qd.klines.batch(),让批量 K 线查询函数在多个策略中复用?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
Dream-Y.ocean12 小时前
鸿蒙PC平台星图遥感适配实战:基于 Electron 壳方案的纯 JavaScript 遥感图像处理引擎开发
javascript·electron·harmonyos
神仙别闹12 小时前
基于Python实现英词语自动对齐系统
开发语言·python
螺丝钉tina12 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
akinggw12 小时前
libagentcore - 一个基于c++的AI多agent系统升级到2.0版本
开发语言·jvm·c++
老歌老听老掉牙13 小时前
圆柱端面四平面交线及其在yoz面投影的几何解析与 Python 实现
开发语言·python·平面
旖旎夜光13 小时前
【C++ 基础入门】命名空间、输入输出、缺省参数与函数重载
开发语言·c++·笔记·学习
俩个逗号。。14 小时前
Kotlin flow 详解
android·开发语言·kotlin
程序猿乐锅14 小时前
万字详解Single-flight(单飞模式)
java·开发语言·分布式·后端·学习·single-flight