JSON 转义 / 反转义,免费

将字符串中的特殊字符转义以便安全嵌入 JSON,或将 JSON 字符串反转义为普通文本。

工作原理

  1. 粘贴您的字符串:输入要转义的文本 · 可以是含引号、换行、反斜杠或其他特殊字符的普通文本。
  2. 选择转义或反转义:选择是要将文本转义以嵌入 JSON,还是将 JSON 字符串反转义为可读文本。
  3. 复制结果:转义或反转义后的输出会立即显示。复制它即可在您的代码或数据中使用。

为什么使用 JSON 转义?

JSON 字符串有严格的转义规则 · 双引号必须变为 \",换行变为 \n,反斜杠变为 \\,制表符变为 \t。未能正确转义这些字符会引发 JSON 解析错误,破坏 API、配置文件和数据管道。此工具自动处理所有转义和反转义,省去手动查找替换的烦恼,避免因遗漏转义序列引发的隐性 bug。

功能特性

常见问题

JSON 转义处理哪些字符?

JSON 要求转义:双引号(")、反斜杠(\)、正斜杠(/)、换行(\n)、回车(\r)、制表符(\t)、换页(\f)、退格(\b),以及 U+FFFF 以上的 Unicode 字符。此工具会全部处理。

为什么我的 JSON 解析错误与转义有关?

常见原因包括字符串值内未转义的双引号、字符串中的字面换行(应为 \n)和未转义的反斜杠。将您损坏的字符串粘贴到此处,即可正确转义。

结果会包含外层引号吗?

默认情况下,此工具在不加包裹引号的情况下转义内容,以便您将结果粘贴到您的 JSON 字符串中。如需输出两端带双引号,请启用「包含引号」选项。

JSON 字符串规范,一表概览

RFC 8259(2017 年 12 月,由 Tim Bray 编写)是当前的 JSON 标准,取代了 RFC 7159 和原始的 RFC 4627。规范第 7 节列出了字符串字面量中必须转义的字符:

字符 转义 代码点 含义
"\"U+0022引号(结束字符串)
\\\U+005C反斜杠(开始一个转义)
\b\bU+0008退格
\f\fU+000C换页
\n\nU+000A换行符(LF)
\r\rU+000D回车符(CR)
\t\tU+0009制表符
/\/U+002F斜线(可选,但对 HTML 嵌入有用)
control\uXXXXU+0000-U+001F上面未涵盖的任何 C0 控制字符

等效规则在 ECMA-404(第 2 版,2017 年 12 月)中,与 IETF 规范保持同步。JSON 没有八进制(\012)或十六进制(\x41)转义,那些只是 JavaScript;JSON 只支持上面命名的八个转义加上 \uXXXX

\uXXXX 转义和代理对陷阱

JSON 的 \uXXXX 序列编码 UTF-16 代码单元,而不是 Unicode 代码点。这对表情符号和补充平面字符很重要。一个像 😀(U+1F600)这样的单个表情符号不是转义为 \u1F600(那甚至不是合法的四位十六进制形式),而是作为代理对:\uD83D\uDE00,编码高位和低位代理的两个连续转义。高代理范围是 U+D800–U+DBFF;低位是 U+DC00–U+DFFF;它们一起覆盖 U+10000 到 U+10FFFF(补充平面)。

这是表情符号转义错误最常见的来源。RFC 8259 第 7 节明确表示:「要转义不在基本多语言平面中的扩展字符,该字符表示为一个 12 字符序列,编码 UTF-16 代理对。」一个像 👨‍👩‍👧‍👦 这样的四人家庭表情符号,在技术上是四个基础表情符号加上三个零宽连接符,转义为 JSON 字符串中的 30+ 个字符。字节计数相应膨胀:原始 25 个 UTF-8 字节,JSON 转义后 ~58 字节。

JSON 在 HTML、URL、SQL 和 CSV 中

当 JSON 嵌入另一种格式时,JSON 转义本身是不够的。每个上下文都会添加自己的层。

HTML 中的 JSON。经典陷阱是 <script>const data = {{ payload | json }};</script>,当 payload 包含字面子字符串 </script> 时。HTML 解析器在字符串中间关闭脚本标签,JSON 的其余部分在页面上呈现为可见文本。修复是可选的 \/ 转义:<\/script> 是 JSON 有效且 HTML 安全。OWASP 的跨站脚本指南建议在用于 HTML 嵌入的 JSON 中始终转义 <>&'

URL 查询字符串中的 JSON。两层:首先进行 JSON 转义,然后进行百分号编码。{"name":"Bob"} 变成 %7B%22name%22%3A%22Bob%22%7D。忘记百分号编码是 JSON-in-URL 格式错误的第一大原因。

SQL 中的 JSON。存储在 PostgreSQL jsonb 列中,该值是本地解析的,不需要进一步转义。但嵌入在 SQL 字符串字面值(INSERT INTO t (data) VALUES ('{"key":"value"}'))中的 JSON 需要在 JSON 之上进行 SQL 字符串转义:加倍的单引号(''),或者更好,使用参数化查询。

CSV 单元格中的 JSON。CSV 的引号与 JSON 的不同(CSV 使用加倍引号 "",而不是反斜杠序列)。将 JSON 嵌入 CSV 单元格需要两层:首先 JSON 转义字符串,然后 CSV 转义结果(用 "..." 包装,加倍任何内部 ")。

跨语言的运行时 API

语言 编码 解码 备注
JavaScriptJSON.stringifyJSON.parse自 IE 8(2009)以来原生。在所有浏览器和 Node 中可用。
Pythonjson.dumpsjson.loadsensure_ascii=False 放弃非 ASCII 的 \uXXXX 转义。
PHPjson_encodejson_decode自 PHP 5.2(2006 年 11 月)以来原生。JSON_UNESCAPED_UNICODE 标志自 5.4 起。
JavaObjectMapper.writeValueAsStringreadTreeJackson 自 ~2009 以来是事实上的标准。
Gojson.Marshaljson.Unmarshal标准库 encoding/json
Rustserde_json::to_stringserde_json::from_strserde_json crate,无处不在。

JSON 的由来,以及 Crockford 留下了什么

JSON 最初由 Douglas Crockford 于 2001 年在 State Software 形式化,最初用于序列化 JavaScript 对象以进行异步数据交换。第一次公开提及是在 2003 年的 JSON.org 网站上。Crockford 在 2006 年 7 月将其正式指定为 RFC 4627,部分是为了反击大约同一时期的竞争专利尝试。该标准在 2017 年 12 月的 RFC 8259 中移至 STD 90 状态。

JSON 最大的设计决策是使其成为 JavaScript 的一个子集,这样任何 JSON 文档都可以在 JS 解释器中 eval'd 并产生正确的值。这使浏览器的采用变得无障碍,但也永久锁定了一些 JS 怪癖:没有整数类型(所有数字都是 IEEE 754 双精度浮点数)、没有日期类型、没有 NaN 或无穷大。大于 2⁵³−1 的大整数需要字符串序列化("id": "9007199254740993")以避免静默精度损失。

Crockford 故意省略了你可能怀念的东西:注释(「我从 JSON 中删除了注释,因为我看到人们用它们来保存解析指令,这种做法会破坏互操作性」,2012 年 5 月)、尾随逗号模式语言(后来作为 JSON Schema 添加,单独维护,当前草案 2020-12)。社区变体 JSON5 恢复了注释和尾随逗号,但不符合 RFC;它主要用于人工编辑的配置文件(.babelrc.swcrc)。

常见使用场景

常见错误

  1. 使用非 JSON 有效的 JavaScript 转义。用于「A」的 \x41 和用于换行的 \012 在 JS 字符串字面量中有效,但在 JSON 中无效。JSON 只允许八个命名转义加上 \uXXXX
  2. 对 JSON 字符串使用单引号。'hello' 在 JavaScript 中有效,但是无效 JSON。JSON 字符串必须使用双引号。
  3. 不带引号的对象键。{name: "Bob"} 在 JavaScript 中有效,但是无效 JSON。键必须是双引号中的字符串字面量。
  4. 尾随逗号。[1,2,3,] 在 JS 中有效,但是无效 JSON。RFC 8259 明确禁止它们。
  5. 内联注释。// foo/* foo */ 在标准 JSON 中无效。如果需要注释,请使用 JSON5;预期并非每个解析器都接受它。
  6. 将表情符号手工转义为单个 \uXXXXU+FFFF 以上的表情符号需要 UTF-16 代理对,两个 \uXXXX 转义连在一起。

更多常见问题

我应该总是转义正斜杠 / 吗?

不,在 JSON 中,正斜杠 / 允许不转义;转义 \/ 是可选的。例外是当 JSON 嵌入在 HTML <script> 标签内时:将 / 转义为 \/ 可防止字面子字符串 </script> 过早关闭标签。一些编码器(PHP 中的 JSON_HEX_TAG、自定义 JS 替换)这样做;大多数不会。

为什么 JSON.stringify 转义我的非 ASCII 字符?

默认情况下不会。JavaScript 中的 JSON.stringify("café") 产生带字面 é"café"。你可能看到的是另一个库:Python 的 json.dumps 默认为 ensure_ascii=True 并将 ASCII 之外的所有内容转义为 \uXXXX;PHP 的 json_encode 的行为类似,除非你传递 JSON_UNESCAPED_UNICODE。两种行为都是有效的 JSON,但文件大小和可读性不同。

JSON 可以存储二进制数据吗?

不能直接存储。JSON 字符串是 Unicode 字符序列,而不是字节。标准的变通方法是首先对二进制进行 Base64 编码,然后将结果 ASCII 字符串存储为普通 JSON 值。编码后的数据比原始字节大 ~33%。对于非常大的二进制,请使用二进制格式如 BSON、MessagePack 或 CBOR,或单独存储字节并按 URL 引用它们。

为什么有些工具显示 \u00e9 而不是 é?

两者都是同一字符的有效 JSON。"caf\u00e9""café" 解码为相同的字符串。一些编码器为了最大跨编码安全性而转义非 ASCII(输出是纯 ASCII,因此消费者的编码无关紧要),其他保留原始 UTF-8 以提高可读性。根据消费你的 JSON 的内容来选择。

我的文本会上传到任何地方吗?

不会。该工具完全在客户端使用浏览器的原生 JSON.stringifyJSON.parse API。没有网络调用、没有分析、没有日志记录。安全地转义 API 令牌、内部数据,或任何你不会粘贴到服务器端转义工具中的内容。

相关工具

免费在线 JSON 格式化器和验证器 JSON 树形查看器,免费 JSONPath 提取器,免费 HTML 实体编码 / 解码器,免费