fetch()
は、(成功した場合) Response
オブジェクトに解決されるpromiseを返します。非常に一般的なことは、すぐに Response.json()
を呼び出して、応答本文をJSONオブジェクトに変換することです。
応答本文が有効なJSONでない場合、Response.json()
promiseはエラーで失敗します。メッセージは次の行に沿ったものです。
位置0のJSONの予期しないトークンX
問題を診断しようとするとき、それはあまり役に立ちません。理想的には、サーバーのコンテンツを表示できるようにしたい(これは多くの場合エラーメッセージです)。
ただし、ストリームは_Response.body
_で1回しか読み取れないようです(少なくともChromeでは)。 (読み取り専用の _Response.bodyUsed
_ フラグもあります。)Response.json()
が本文をJSONに変換しようとしたときに既に発生しているため、本文は永久に失われているように見えますJSONの解析に失敗した場合。
元のfetch
Promiseが解決したときに、元の応答本文を手動で読み取る(そしてJSONに変換する)以外に、元の応答本文を復元する方法はありますか?
Response.clone()
を使用して、Response
を複製します。
_let clone = response.clone();
_
または、ReadableStream
を返すResponse.body.getReader()
を使用して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
});
};