You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fetch请求解析JSON失败转文本报错:响应体流已读取

问题:fetch解析JSON失败后调用text()报错:body stream already read

需求

从服务器获取数据,优先尝试将响应体解析为JSON,解析失败则返回纯文本。

原实现代码

fetch(`/devapi/${url}`, {
    method: 'GET',
    headers: new Headers({
      Authorization: `Bearer ${localStorage.getItem("token")}`,
    }),
  })
    .then((res) =>
      res
        .json()
        .then((res) => res?.body?.data || res?.body || res)
        .catch((err) => res.text())
    )
    .then((val) => console.log(val));

报错信息

Failed to execute 'text' on 'Response': body stream already read

问题根源

Response的body是一次性可读流,调用json()时会把整个流读取并消耗掉,流被读取后就没法再调用text()或其他body解析方法,自然会触发这个报错。

解决方案

方案一:先读文本再尝试解析(推荐)

先把响应体读取成原始文本,再尝试转JSON,失败直接返回文本。全程只读取一次流,性能更好逻辑也清晰。

fetch(`/devapi/${url}`, {
    method: 'GET',
    headers: new Headers({
      Authorization: `Bearer ${localStorage.getItem("token")}`,
    }),
  })
    .then(res => res.text()) // 先读文本,只消耗一次流
    .then(text => {
      try {
        const json = JSON.parse(text);
        return json?.body?.data || json?.body || json;
      } catch (err) {
        // 解析失败返回原文本
        return text;
      }
    })
    .then(val => console.log(val));

方案二:克隆Response对象

通过clone()复制一份Response,分别用原对象和克隆对象执行json、text解析。这种方式会读取两次流,适合特殊场景下使用。

fetch(`/devapi/${url}`, {
    method: 'GET',
    headers: new Headers({
      Authorization: `Bearer ${localStorage.getItem("token")}`,
    }),
  })
    .then(res => {
      const resClone = res.clone();
      return res.json()
        .then(json => json?.body?.data || json?.body || json)
        .catch(() => resClone.text());
    })
    .then(val => console.log(val));

内容的提问来源于stack exchange,提问作者Sherif eldeeb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 19:01:01