JSON转义是开发者在处理API、数据库和数据交换时必须掌握的基本技能。理解何时以及如何转义JSON字符串可以防止解析错误、安全漏洞和数据损坏。本指南涵盖了JSON转义和反转义的所有知识。
📋 目录
核心要点
- 转义必需字符:双引号(
")、反斜杠(\)和控制字符必须在JSON字符串中转义。 - 使用标准库:始终使用内置的JSON函数(
JSON.stringify、json.dumps)而不是手动转义。 - 嵌套JSON:在JSON中嵌入JSON时,内部JSON必须作为字符串进行转义。
- Unicode支持:JSON支持使用
\uXXXX格式进行Unicode转义。 - 验证:转义/反转义后始终验证JSON以确保数据完整性。
需要快速转义或反转义JSON?试试我们的免费在线工具:
什么是JSON转义?
JSON转义是将字符串中的特殊字符转换为可以安全包含在JSON文档中的转义序列的过程。这确保JSON保持有效且可解析。
为什么需要转义
看这个例子:
json
// 无效JSON - 未转义的引号破坏了结构
{ "message": "他说"你好"" }
// 有效JSON - 引号已转义
{ "message": "他说\"你好\"" }
没有转义,特殊字符可能会:
- 破坏JSON语法
- 导致解析错误
- 创建安全漏洞(注入攻击)
- 在传输过程中损坏数据
转义 vs 编码
| 术语 | 描述 | 示例 |
|---|---|---|
| 转义 | 将特殊字符转换为转义序列 | " → \" |
| 编码 | 将整个字符串转换为不同格式 | 字符串 → Base64 |
| 序列化 | 将对象转换为JSON字符串 | 对象 → {"key":"value"} |
必须转义的字符
根据JSON规范(RFC 8259),这些字符必须转义:
| 字符 | 转义序列 | 描述 |
|---|---|---|
" |
\" |
双引号 |
\ |
\\ |
反斜杠 |
/ |
\/ |
正斜杠(可选) |
\b |
\\b |
退格符 |
\f |
\\f |
换页符 |
\n |
\\n |
换行符 |
\r |
\\r |
回车符 |
\t |
\\t |
制表符 |
| 控制字符 | \uXXXX |
Unicode转义 |
可视化示例
javascript
// 包含特殊字符的原始字符串
const original = '第一行\n第二行\t制表符 "引号"';
// JSON转义后
const escaped = "第一行\\n第二行\\t制表符 \\\"引号\\\"";
// JSON格式
{
"text": "第一行\n第二行\t制表符 \"引号\""
}
如何转义JSON字符串
方法1:使用我们的在线工具
转义JSON最简单的方法是使用我们的在线工具:
- 访问 JSON转义工具
- 在输入区域粘贴你的JSON或字符串
- 点击"转义"来转换特殊字符
- 复制转义后的结果
方法2:使用内置函数
JavaScript:
javascript
// 为JSON转义字符串
const str = '你好 "世界"\n新行';
const escaped = JSON.stringify(str);
// 结果: "你好 \"世界\"\n新行"
// 反转义JSON字符串
const unescaped = JSON.parse(escaped);
// 结果: 你好 "世界"
// 新行
Python:
python
import json
# 为JSON转义字符串
original = '你好 "世界"\n新行'
escaped = json.dumps(original, ensure_ascii=False)
# 结果: "你好 \"世界\"\n新行"
# 反转义JSON字符串
unescaped = json.loads(escaped)
# 结果: 你好 "世界"
# 新行
Java:
java
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = new ObjectMapper();
// 转义
String original = "你好 \"世界\"\n新行";
String escaped = mapper.writeValueAsString(original);
// 反转义
String unescaped = mapper.readValue(escaped, String.class);
处理嵌套JSON
最常见的挑战之一是在JSON中嵌入JSON。这需要将内部JSON作为字符串进行转义。
问题
javascript
// 你想在另一个JSON中存储这个JSON
const innerJson = { "name": "张三", "age": 30 };
// 错误 - 这创建了嵌套对象,而不是字符串
const wrong = { "data": innerJson };
// 结果: { "data": { "name": "张三", "age": 30 } }
// 正确 - 先stringify创建转义字符串
const correct = { "data": JSON.stringify(innerJson) };
// 结果: { "data": "{\"name\":\"张三\",\"age\":30}" }
多层嵌套
javascript
// 第1层: 原始对象
const level1 = { message: "你好" };
// 第2层: 嵌入到另一个JSON
const level2 = { payload: JSON.stringify(level1) };
// { "payload": "{\"message\":\"你好\"}" }
// 第3层: 再次嵌入
const level3 = { wrapper: JSON.stringify(level2) };
// { "wrapper": "{\"payload\":\"{\\\"message\\\":\\\"你好\\\"}\"}" }
转义序列增长
| 嵌套层级 | 引号表示 |
|---|---|
| 第0层 | " |
| 第1层 | \" |
| 第2层 | \\\" |
| 第3层 | \\\\\\\" |
多语言实现
JavaScript/Node.js
javascript
// 转义JSON字符串
function escapeJson(str) {
return JSON.stringify(str).slice(1, -1);
}
// 反转义JSON字符串
function unescapeJson(str) {
return JSON.parse(`"${str}"`);
}
// 将整个JSON对象转义为字符串
function jsonToEscapedString(obj) {
return JSON.stringify(JSON.stringify(obj));
}
// 示例
console.log(escapeJson('你好 "世界"'));
// 输出: 你好 \"世界\"
console.log(unescapeJson('你好 \\"世界\\"'));
// 输出: 你好 "世界"
Python
python
import json
def escape_json_string(s):
"""转义字符串用于JSON。"""
return json.dumps(s, ensure_ascii=False)[1:-1]
def unescape_json_string(s):
"""反转义JSON转义的字符串。"""
return json.loads(f'"{s}"')
def json_to_escaped_string(obj):
"""将JSON对象转换为转义字符串。"""
return json.dumps(json.dumps(obj, ensure_ascii=False), ensure_ascii=False)
# 示例
print(escape_json_string('你好 "世界"'))
# 输出: 你好 \"世界\"
print(unescape_json_string('你好 \\"世界\\"'))
# 输出: 你好 "世界"
Go
go
package main
import (
"encoding/json"
"fmt"
)
func escapeJsonString(s string) string {
b, _ := json.Marshal(s)
return string(b[1 : len(b)-1])
}
func main() {
original := `你好 "世界"`
escaped := escapeJsonString(original)
fmt.Println(escaped)
// 输出: 你好 \"世界\"
}
PHP
php
<?php
// 转义JSON字符串
function escapeJsonString($str) {
$encoded = json_encode($str, JSON_UNESCAPED_UNICODE);
return substr($encoded, 1, -1);
}
// 反转义JSON字符串
function unescapeJsonString($str) {
return json_decode('"' . $str . '"');
}
// 示例
echo escapeJsonString('你好 "世界"');
// 输出: 你好 \"世界\"
?>
常见使用场景
1. API请求/响应
javascript
// 在API请求中发送JSON数据
const requestBody = {
query: 'SELECT * FROM users WHERE name = "张三"',
metadata: JSON.stringify({ source: "api", timestamp: Date.now() })
};
fetch('/api/data', {
method: 'POST',
body: JSON.stringify(requestBody)
});
2. 数据库存储
sql
-- 在数据库中存储JSON
INSERT INTO logs (data) VALUES ('{"message":"用户说\"你好\""}');
-- 查询转义的JSON
SELECT * FROM logs WHERE data LIKE '%\"你好\"%';
3. 配置文件
json
{
"script": "echo \"Hello World\"",
"template": "{\"name\": \"{{username}}\"}",
"regex": "\\d+\\.\\d+"
}
4. 日志消息
javascript
// 安全地记录JSON
const userData = { name: '张三 "开发者"', role: 'admin' };
console.log(`用户数据: ${JSON.stringify(userData)}`);
// 输出: 用户数据: {"name":"张三 \"开发者\"","role":"admin"}
常见错误
❌ 手动转义
javascript
// 错误 - 不完整的手动转义
const bad = str.replace(/"/g, '\\"');
// 正确 - 使用JSON.stringify
const good = JSON.stringify(str);
❌ 双重转义
javascript
// 错误 - 转义已经转义的字符串
const alreadyEscaped = '你好 \\"世界\\"';
const doubleEscaped = JSON.stringify(alreadyEscaped);
// 结果: "你好 \\\\\"世界\\\\\""
// 正确 - 先检查是否已经转义
❌ 忘记控制字符
javascript
// 错误 - 只转义引号
const bad = str.replace(/"/g, '\\"');
// 遗漏: \n, \r, \t, \b, \f, \\
// 应该使用JSON.stringify
❌ 错误的反转义
javascript
// 错误 - 使用eval(安全风险!)
const bad = eval(`"${escapedString}"`);
// 正确 - 使用JSON.parse
const good = JSON.parse(`"${escapedString}"`);
常见问题
JSON转义和URL编码有什么区别?
| 方面 | JSON转义 | URL编码 |
|---|---|---|
| 用途 | 安全的JSON字符串 | 安全的URL |
| 引号 | " → \" |
" → %22 |
| 空格 | 不转义 | → %20 或 + |
| 换行 | \n → \\n |
\n → %0A |
什么时候应该转义JSON?
在以下情况下转义JSON:
- 在另一个JSON中嵌入JSON作为字符串
- 将JSON作为文本存储在数据库中
- 通过不处理原始JSON的系统传输JSON
- 在JSON响应中包含用户输入
如何处理Unicode字符?
javascript
// Unicode字符可以转义为\uXXXX
const str = "Hello 世界";
const escaped = JSON.stringify(str);
// 结果: "Hello 世界" 或 "Hello \u4e16\u754c"
// 两者都是有效的JSON
可以不用库转义JSON吗?
虽然可能,但不推荐:
javascript
// 手动转义(不推荐)
function manualEscape(str) {
return str
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/\t/g, '\\t')
.replace(/\f/g, '\\f')
.replace(/\b/g, '\\b');
}
// 更好: 使用JSON.stringify
如何验证转义后的JSON?
javascript
function isValidJson(str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
// 测试
console.log(isValidJson('{"name":"张三"}')); // true
console.log(isValidJson('{"name":"张三}')); // false
总结
JSON转义对于处理API、数据库和数据交换至关重要。通过理解哪些字符需要转义并使用正确的工具,你可以避免常见陷阱并确保JSON数据保持有效和安全。
快速参考:
- ✅ 使用
JSON.stringify()进行转义 - ✅ 使用
JSON.parse()进行反转义 - ✅ 转换后验证JSON
- ❌ 不要手动转义字符串
- ❌ 不要使用
eval()进行反转义
需要快速转义或反转义JSON?使用我们的免费在线工具: