fetch 不校验 json 标准性,非标响应(如注释、单引号、html 错误页)会导致 response.json() 抛错;应先检查 content-type,再用 .text() + try/catch + json.parse() 安全解析并清洗数据,对封装体需解包校验 code/data,配合兜底策略保障健壮性。

Fetch 本身不负责“校验 JSON 格式是否标准”,它只按响应头和内容尝试解析。当后端返回非标准 JSON(比如带注释、尾逗号、单引号、HTML 错误页、空响应、或包裹了额外字段的“JSON 封装体”)时,response.json() 会直接抛错,常见报错是 Unexpected token 或 Unexpected end of JSON input。关键不是绕过解析,而是提前识别、降级处理或清洗数据。
先判断响应类型,再决定怎么读
不能默认调用 .json()。要结合 response.headers.get('content-type') 和业务预期做分流:
- 如果 content-type 不含
application/json(比如是text/html或text/plain),就别硬用.json(),改用.text()拿原始字符串再人工处理 - 如果 content-type 是 JSON,但实际内容可能不规范(如 Django 的
JsonResponse有时混入调试信息),建议先.text()读取,再用try/catch + JSON.parse()安全解析 - 对纯文本接口(如日志、配置片段),直接
.text()更稳妥,避免解析失败中断流程
用 .text() + JSON.parse() 替代 .json() 做可控解析
response.json() 是黑盒,出错就崩;而 response.text().then(str => JSON.parse(str)) 把字符串拿到手后,你可以清洗、截断、替换非法字符,再解析:
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
- 去掉开头 BOM 或不可见控制符:
str.trim().replace(/^\uFEFF/, '') - 修复常见非标写法:把单引号换成双引号、补全缺失逗号(谨慎)、删掉 JS 注释(仅限你完全信任来源)
- 提取 JSON 片段:如果响应是
"data: {...}"这种格式,可用正则匹配{.*}再解析 - 示例:
const text = await response.text();
let data;
try {
data = JSON.parse(text);
} catch (e) {
console.warn('JSON parse failed, raw text:', text);
throw e;
}
处理“伪 JSON”封装体(如 { code: 0, data: {...} })
很多后端 API 不直接返回纯数据,而是统一包装成 { code, msg, data } 结构。这时不能指望 .json() 后直接用 data.xxx —— 得先解包:
- 先确保响应成功(
response.ok)且状态码合理(如 200) - 再
.json()解析整个响应体,然后检查data字段是否存在、是否为对象 - 若
code !== 0或!data,应视为业务错误,而非解析失败,按业务逻辑提示用户 - 避免嵌套太深:不要写
res.data.items[0].user.name这类链式访问,先用可选链?.或空值合并??防崩
兜底策略:容错读取 + 明确错误反馈
真实项目中,非标响应往往暴露后端问题。前端要做的是“不崩溃、可诊断、有提示”:
- 始终用
try/catch包住解析逻辑,捕获SyntaxError和网络异常 - 记录原始响应体(尤其开发环境),方便排查是后端发错,还是前端解析方式不对
- 对无法解析的响应,提供友好 fallback:比如显示“数据加载异常,请稍后重试”,而不是白屏或报错堆栈
- 必要时加超时控制(fetch 本身不支持,需用
AbortController),防止卡死在无效响应上
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










