悦省yueser.com

← 全部指南

JSON、HTML、SQL 转义:三种上下文别混用

先选目标上下文(JSON 字符串、HTML 实体、SQL 字面量),粘贴内容,点「转义」;要反向操作就点「还原」。JSON 模式给出的是引号内部的内容,不含首尾双引号。

打开工具:文本转义

什么时候真的需要转义

手写 JSON 请求体,要把一段用户输入塞进某个字符串值里:JSON 模式返回的正是引号内部那份结果,反斜杠、双引号、换行、制表符都已经处理好,直接替换占位符即可。

排查多层转义:日志或接口字段里出现 " 这种字样,把它贴进 HTML 模式还原一次;如果还剩下 ",说明至少转了两层,继续还原直到可读为止。

临时查数据时拼一条带引号的 SQL 字面量,让语句先别报语法错。注意这只适合手工调试,不适合写进应用代码。

怎么做才不出错

JSON 模式只处理单个字符串值,不校验整段文档。它不会替你做括号配对,也不会检查逗号;要验证完整 JSON,请用 JSON 格式化工具。

还原时它把整串当作一个 JSON 字符串解析,串里出现未转义的引号会直接报错,而不是返回半截结果。所以别拿它去猜一个残缺转义串的含义。

要把结果嵌进 HTML 的 <script> 里,JSON 转义还不够:还要处理 </script> 以及 U+2028、U+2029,否则脚本会提前闭合或语法报错。这是 JSON 与 HTML 两个上下文的交界,容易被忽略。

HTML 模式只替换 &、<、>、双引号、单引号五个字符,能防止文本被当成标签解析,但不构成 XSS 防护:on* 事件属性、javascript: 伪协议、没有引号的属性都原样通过。清洗用户提交的富文本要用 DOMPurify 这类白名单清洗器。

SQL 模式只是把单引号翻倍,这是标准 SQL 里引用字面量的写法。MySQL 默认仍把反斜杠当转义符,反斜杠加单引号依然能逃出去;数值位置、ORDER BY 的列名、LIKE 里的 % 和 _ 更不在保护范围内。

转义不幂等,这是最常见的误解。第一次把 & 变成 &amp;,第二次会把 &amp; 里的 & 再转一遍,得到 &amp;amp;。所以页面上如果直接看到 &amp; 或 &amp;amp; 字样,通常说明数据比预期多转义了一层。正确做法是只在写入目标上下文的那一刻转义一次;拿到别人转义过的字段时,先确认它转了几层,再一次还原到位。

替代方案与局限

JSON 交给语言内置的序列化:JSON.stringify 会正确处理转义,还能一次处理整个对象,不用手工拼字符串。

HTML 用模板引擎的自动转义,或语言标准库的 html.escape;清洗富文本用 DOMPurify 这类白名单库,不要自己写正则。

SQL 用参数化查询或预编译语句(? 或 $1),把值当数据传,而不是拼进语句。这是唯一能覆盖数值、列名、通配符的方案;转义只能当兜底。

本工具的限制很明确:JSON 模式只处理单个字符串值;HTML 模式只覆盖五个字符;SQL 模式只翻倍单引号,在 MySQL 反斜杠模式和数值位置不构成防护。

常见问题

SQL 转义能防 SQL 注入吗?

单靠它不行。SQL 模式只是把单引号变成两个,这是标准 SQL 里引用字面量的写法;但 MySQL 默认开启反斜杠转义,反斜杠加单引号依然能逃出去,GBK 这类宽字节编码历史上还有专门的绕过手法;数值参数、ORDER BY 的列名、LIKE 里的 % 和 _ 更不是加引号能解决的。它只适合临时手工查一下数据,让字符串别报语法错。应用代码里请用参数化查询或预编译语句。

为什么 JSON 转义结果没有首尾的双引号?

因为工具给的是字符串内部的内容,方便你直接放进已有的双引号之间。需要完整 JSON 字面量时自己补外层双引号。还原时它把整串当一个 JSON 字符串解析,串里出现未转义的引号会直接报错,而不是返回半截结果,所以别拿它去猜一个残缺转义串的含义。

连续转义两次,& 变成了 &amp;amp;,是 bug 吗?

不是。转义本来就不幂等:第一次把 & 变成 &amp;,第二次把 &amp; 里的 & 再转一遍,得到 &amp;amp;。这正是页面上有时会直接看到 &amp; 或 &amp;amp; 字样的原因——数据比预期多转义了一层,却没有相应还原。正确做法是只在写入目标上下文的那一刻转义一次;拿到别人转义过的字段时,先确认它到底转了几层,再一次还原到位。

相关工具:文本转义