必须 await + try/catch 双重包裹 response.json(),先校验 response.ok,204 用 response.text() 判断空字符串,解析前检查响应内容类型,解析后用可选链和类型判断验证数据结构。

直接用 response.json() 不加防护,很容易在解析阶段就崩溃。核心不是“怎么写对”,而是“怎么防错”——因为报错往往来自响应内容本身不可靠,而非代码语法错误。
必须 await + try/catch 双重包裹
response.json() 返回的是 Promise,不 await 就等于拿了个未执行的解析任务;没 try/catch 则任何异常(网络中断、CORS 拒绝、JSON 格式损坏)都会导致静默失败或页面报错。
- 在 async 函数里写
const data = await response.json(),不能省略await - 整个 fetch 调用必须包在
try { ... } catch (err) { ... }中 - 不要只捕获
catch(err),可细分判断:err.name === 'SyntaxError'表示 JSON 解析失败,err.name === 'TypeError'多为网络问题
先校验 response.ok,再解析 JSON
response.ok 是最轻量的状态守门员。404、500、204 等非成功状态下,response.json() 仍会尝试解析,但后端可能返回 HTML 错误页或空响应体,直接触发 Unexpected token < 或 Unexpected end of JSON input。
- 加上
if (!response.ok) throw new Error(`HTTP ${response.status}`) - 特别注意 204 No Content:它没有响应体,
response.json()必然失败,此时应改用response.text()并判断是否为空字符串
解析前检查原始响应内容类型和结构
别假设后端永远返回合法 JSON。HTML 页面、JSONP、带 BOM 的文本、被截断的数据,都可能混进响应体。
立即学习“Java免费学习笔记(深入)”;
- 在 catch 块中加
console.log(await response.text()),一眼看出返回的是不是 JSON - 若开头是
<!DOCTYPE、<html或<div,基本可确认是网关跳转或错误页 - 对空格、BOM 字符做预处理:
text.trim().replace(/^\uFEFF/, ''),再传给JSON.parse()(适用于手动解析场景)
解析后验证数据结构再使用
即使 response.json() 成功,也可能得到字段缺失、类型错乱的对象,比如 data.user.name.toUpperCase() 在 data.user 为 undefined 时直接报错。
- 用可选链操作符:
data?.user?.profile?.name - 取关键字段前加存在性判断:
if (Array.isArray(data.features)) { ... } - 避免链式调用前反复
JSON.stringify()——response.json()已返回对象,再 stringify 就变字符串,.features必然undefined


















