当服务器返回空响应时,fetch不会报错,但直接调用json()或text()可能异常;应先判断响应是否有内容体,再选择解析方式:对204/205状态码跳过解析,用text()读取后判空并按需json.parse,注意用clone()避免流已读完陷阱。

当服务器返回空响应(如状态码 204 No Content、205 Reset Content,或响应体为空字符串但状态码为 200)时,fetch 不会报错,但直接调用 response.json() 或 response.text() 可能抛出异常或得到意外结果。关键在于先判断响应是否有内容体,再选择合适的解析方式。
检查响应是否含可读内容体
HTTP 规范中,204 和 205 状态码明确禁止包含响应体;部分 API 也可能对成功操作返回空 body 的 200。可通过 response.headers.get('content-length') 或更可靠的方式 —— 检查 response.bodyUsed 和状态码来预判:
- 若
response.status === 204 || response.status === 205,直接跳过解析,视作“成功无数据” - 若
response.headers.has('content-length') && response.headers.get('content-length') === '0',大概率无内容体 - 更稳妥的做法:用
response.clone().text()尝试读取,再判断是否为空字符串(注意 clone 后原 response 仍可用)
安全读取响应体的通用写法
避免 json() 在空响应上失败,推荐统一用 text() 获取原始字符串,再按需解析:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
const text = await response.text();- 若
text.trim() === '',说明响应体为空,可直接返回null或{} - 否则尝试
JSON.parse(text),并包裹try/catch处理非法 JSON
封装一个健壮的 fetch 辅助函数
把上述逻辑收拢,减少重复判断:
async function safeFetch(url, options = {}) {
const res = await fetch(url, options);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const text = await res.text();
if (!text.trim()) return null; // 或 return {}
try {
return JSON.parse(text);
} catch (e) {
return text; // 非 JSON 内容(如纯文本、XML)可直接返回
}
}
注意流已读完的陷阱
response.json()、response.text() 等方法会消耗响应流,调用一次后再次调用会失败(bodyUsed: true)。若需多次读取,务必先用 response.clone():
- 错误示例:
await res.json(); await res.text();→ 第二行报错 - 正确做法:
const clone = res.clone(); await res.json(); await clone.text(); - 或统一走
text(),再根据需要解析,避免多次消费流
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










