从JavaScript的fetch中重读响应主体

Cra*_*ker 16 javascript json stream httpresponse fetch

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

如果响应主体无效JSON,则Response.json()承诺失败并显示错误.消息是这样的:

位于0的JSON中出现意外的标记X​​.

在尝试诊断问题时,这不是很有用; 理想情况下,我希望能够从服务器中看到内容(这通常是一条错误消息).

但是,您似乎只能Response.body一次阅读流(至少在Chrome中).(甚至还有一个只读Response.bodyUsed标志.)当Response.json()尝试将主体转换为JSON 时已经发生这种情况,因此在JSON解析失败的情况下,主体似乎永远丢失.

有没有办法恢复原始的响应体...当原始的fetchPromise结算时,没有手动读取它(然后转换为JSON)?

gue*_*314 26

使用Response.clone()到克隆Response

let clone = response.clone();
Run Code Online (Sandbox Code Playgroud)

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

  • 我收到“无法在“响应”上执行“克隆”:响应主体已被使用” (2认同)

Jar*_*a X 8

我不得不处理一个偶尔会破坏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
    });
};
Run Code Online (Sandbox Code Playgroud)

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
    });
};
Run Code Online (Sandbox Code Playgroud)