从JavaScript's fetch中重新读取响应体

Reread a response body from JavaScript's fetch

本文关键字:新读取 读取 响应 JavaScript fetch      更新时间:2023-09-26

fetch()返回promise(如果成功)解析为Response对象。一个非常常见的事情是立即调用Response.json()将响应体转换为JSON对象。

如果响应体不是有效的JSON,则Response.json()承诺失败并出现错误。该消息类似于以下内容:

JSON中位置0的意外token X

当试图诊断问题时,这不是很有帮助;理想情况下,我希望能够看到来自服务器的内容(这通常是一个错误消息)。

然而,似乎你只能在Response.body读取流一次(至少在Chrome中)。(甚至还有一个只读的Response.bodyUsed标志。)当Response.json()试图将body转换为JSON时,已经发生了这种情况,因此在JSON解析失败的情况下,body似乎永远丢失了。

是否有办法恢复原来的响应体…当原始fetch承诺解析时,缺少手动读取它(然后转换为JSON) ?

使用Response.clone()克隆Response

let clone = response.clone();

或者,使用Response.body.getReader()返回ReadableStream来读取Response作为流,TextDecoder()Uint8Array数据流转换为文本。

我必须处理一个偶尔搞砸JSON响应的API -在返回response.json()之前,我对响应对象进行了克隆。使用catch块,我可以确定错误是否是SyntaxError,并使用响应克隆

的文本结果继续修复错误。

:

var brokenJson = function (url) {
    var responseCopy;
    return fetch(url)
    .then(function (response) {
        responseCopy = response.clone();
        return response.json();
    }).catch(function (err) {
        if (err instanceof SyntaxError) {
            return responseCopy.text()
            .then(function(data) {
                return fixJson(data);
            });
        }
        else {
            throw err;
        }
    }).then(function (json) {
        // do things
    });
};

fixJson只是一个修复接收数据的函数-在我的情况下,当它是破碎的JSON时,它总是以同样的方式被打破-我认为它有一个额外的前导{或尾随}-无法回忆

重新阅读问题,你更可能想要将错误记录到控制台,而不是修复json -易于重写:

var brokenJson = function (url) {
    var responseCopy;
    return fetch(url)
    .then(function (response) {
        responseCopy = response.clone();
        return response.json();
    }).catch(function (err) {
        if (err instanceof SyntaxError) {
            return responseCopy.text()
            .then(function(text) {
                console.error(text);
                throw err;
            });
        }
        else {
            throw err;
        }
    }).then(function (json) {
        // do things
    });
};

将response.json()分配给变量并返回它对我有效。Clone()再次说它被锁定了。

fetch("http://localhost:3000/watchlist")
    .then(response => {
      var res = response.json();
      return res;
    })
    .then(data => {
      console.log(data);
      this.setState({ data });
    });

我使用JSON.parse(response.resp.data),因为不知怎的克隆不起作用