提问背景 Question:
js默认没有
```
unction escapeHtml(htmlString) {
return htmlString
.replace(/&/g, "&") // 必须首先转义&符号
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'"); // 或者 ' 或 ' (部分浏览器可能不支持)
}
```
这样的函数吗?
JavaScript HTML转义实现与原理
是的,JavaScript 确实没有默认内置像 escapeHtml 这样可以直接调用的全局函数。
尽管这是 Web 开发中极为常见的安全与展示需求,但在 ECMAScript 核心规范中,并没有包含此类专门用于 HTML 实体编码的方法。这主要是因为 JavaScript 作为一门通用语言,不仅运行在浏览器端,还广泛运行在 Node.js 等无 HTML 上下文的服务器环境。
不过,在实际开发中,我们可以通过以下两种最常用的方式来实现这个功能。
方法一:使用正则表达式(最推荐,前后端通用,性能最好)
这就是你刚才写出的方法,它是最经典的纯 JS 实现方式。注意:必须最先转义 &,否则后续转义出来的 &、< 中的 & 会被二次转义。
function escapeHtml(htmlString) {
if (typeof htmlString !== 'string') {
return htmlString;
}
return htmlString
.replace(/&/g, "&") // 必须最先转义
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'"); // 兼容性最好的单引号转义
}
// 测试
const rawHtml = '<div class="test">Hello & "World"</div>';
console.log(escapeHtml(rawHtml));
// 输出: <div class="test">Hello & "World"</div>
方法二:利用浏览器 DOM 属性(仅限浏览器环境)
如果你是在浏览器端运行代码,可以巧妙地利用 DOM 节点的 textContent 属性。当你把含有 HTML 字符的字符串赋值给节点的 textContent 时,浏览器会自动在内存中对其进行转义,之后再读取 innerHTML 即可拿到转义后的文本。
function escapeHtmlDOM(htmlString) {
const div = document.createElement('div');
div.textContent = htmlString;
return div.innerHTML;
}
// 测试
console.log(escapeHtmlDOM('<script>alert(1)</script>'));
// 输出: <script>alert(1)</script>
优缺点对比:
- 优点:无需编写和维护正则表达式,完全依赖浏览器底层的解析,绝对安全。
- 缺点:无法在 Node.js 服务端运行;由于涉及 DOM 节点的创建和内存操作,在大数据量频繁调用时性能不如方法一(正则)。
补充:现代框架中的处理
如果你在项目中使用的是现代前端框架(如 Vue 的 {{ message }} 或 React 的 {message}),框架在将数据渲染到页面时,默认就已经在底层调用了类似的转义函数来保障安全性(防范 XSS 攻击)。只有当你显式使用 v-html 或 dangerouslySetInnerHTML 时,才会跳过转义。