应始终用 try...catch 包裹 JSON.parse(),提前过滤空值与空白字符,检查响应头及 HTML 片段,结合可选链、类型守卫或 zod 校验防御结构风险,并采用 safeFetchJson 模板统一处理。

JSON.parse() 会直接报错,怎么避免崩溃?
API 返回的不是标准 JSON 字符串时,JSON.parse() 会抛出 SyntaxError,导致整个流程中断。不能假设后端永远返回合法 JSON —— 网络截断、服务降级、调试注入都可能造成响应体损坏。
- 始终用
try...catch包裹JSON.parse(),不要依赖response.ok或状态码判断内容是否可解析 - 检查响应头
Content-Type是否含application/json,但不作为唯一依据(有些 API 错误时仍返回该类型) - 对空字符串、
null、undefined、纯空白字符提前过滤,否则JSON.parse('')或JSON.parse(' ')同样报错
后端返回 HTML 或错误页面,怎么识别并处理?
常见于网关未正确透传、认证失败跳转、Nginx 502/503 页面被当 JSON 返回。此时 JSON.parse() 报错信息通常是 Unexpected token 或类似提示。
- 在
catch块中检查原始响应文本是否以/code>、、开头,快速判断是否混入 HTML- 记录完整响应体(
response.text())用于排查,而非只打印错误信息- 可封装一个带类型预检的解析函数:
safeJsonParse(text: string): { ok: boolean; data: any; error?: Error }如何防止解析出非预期结构导致运行时错误?
即使 JSON 解析成功,字段缺失、类型错乱(比如
id是字符串却当成数字用)、嵌套层级不存在等问题仍会导致后续代码崩在data.user.profile.name.toUpperCase()这类访问上。- 不要信任任何字段存在,用可选链
?.和空值合并??:例如data?.user?.profile?.name ?? 'Anonymous' - 对关键字段做类型守卫,比如
typeof data?.count === 'number',而非直接参与计算 - 如果业务逻辑强依赖结构,考虑用运行时校验库(如
zod或io-ts),但注意 bundle size 影响
fetch + JSON 处理的最小安全模板长什么样?
不是写个
await res.json()就完事。浏览器原生res.json()内部调用的就是JSON.parse(),一样会 throw,且无法拦截原始文本。立即学习“Java免费学习笔记(深入)”;
async function safeFetchJson(url) { const res = await fetch(url); const text = await res.text(); try { const data = JSON.parse(text); return { ok: true, data }; } catch (e) { return { ok: false, error: e, status: res.status, rawText: text.slice(0, 200), // 截取前 200 字符防日志爆炸 }; } }这个模式能同时拿到原始响应、错误上下文和结构化结果。真正难的不是解析,是判断“这到底算不算一次有效 API 调用”——有时候 200 状态码返回了 JSON 格式的错误对象,这时候你得看
data.code === 0才算成功,而不是只看 HTTP 状态。 - 记录完整响应体(











