JSON.parse()不安全,需校验+异常捕获;它只做语法解析,不校验语义或来源,可能因HTML响应、BOM、控制字符等抛错;safeParseJSON应预清洗、捕获SyntaxError、类型断言。
直接用 JSON.parse() 解析字符串是安全的——前提是数据来源可信;一旦涉及用户输入、API 响应或 localStorage 读取,就必须加校验和异常捕获,否则会因格式错误或恶意构造触发 SyntaxError 或静默失败。
JSON.parse()
它只做语法解析,不校验语义。比如:"null"、"true"、"123" 都是合法 JSON 字符串,但可能不符合你预期的数据结构;更危险的是,某些服务返回的响应体看似 JSON,实则混入 HTML(如 500 错误页),此时 JSON.parse() 会直接抛错中断流程。
Uncaught SyntaxError: Unexpected token (
说明服务器返回了 HTML)
response.ok 就调用 response.json(),或从 localStorage.getItem('config') 读取后直 parseJSON.parse() 不处理编码问题,UTF-8 BOM、不可见控制字符(如 \u2028、\u2029)也可能导致解析失败核心是三件事:预清洗、异常捕获、类型断言。不要依赖 try/catch 吞掉所有错误,要区分语法错误和其他异常。
function safeParseJSON(str) {
if (typeof str !== 'string') return null;
// 移除常见 BOM 和首尾空白
const trimmed = str.replace(/^\uFEFF/, '').trim();
if (!trimmed) return null;
try {
const parsed = JSON.parse(trimmed);
// 可选:进一步校验是否为 object/array(排除 "hello"、42 等标量)
return (parsed && typeof parsed === 'object') ? parsed : null;
} catch (e) {
if (e instanceof SyntaxError) return null;
throw e; // 其他异常(如内存溢出)不应静默
}
}
null 表示解析失败,而非抛错,便于业务层统一处理response.json() 的区别与协作浏览器原生 response.json() 内部也调用 JSON.parse(),但它还会检查 Content-Type 并在非 application/json 时抛 TypeError。但它**不检查 HTTP 状态码**,404/500 响应仍会进入 .then() 分支并尝试解析。
response.ok,再调用 response.json()
safeParseJSON(await response.text()) 替代 response.json(),可绕过 Content-Type 限制,也避免因服务端 header 错误导致的失败response.text() 返回 Promise,需 await;而 safeParseJSON 是同步函数真正容易被忽略的不是怎么写 parse 函数,而是忘记检查上游数据是否本就「不该是 JSON」——比如后端文档写的是 JSON,但灰度环境实际返回 plain text;或者 localStorage 里存的是旧版字段,新代码按新 schema 解析时字段缺失却不报错。安全处理的本质,是明确每处 JSON 的契约边界,而不是堆砌防御性代码。