web-dev-qa-db-ja.com

javascriptフェッチ-「レスポンス」で「json」の実行に失敗しました:ボディストリームがロックされています

リクエストのステータスが400より大きい場合(400、423、429の状態を試しました)、フェッチは返されたjsonコンテンツを読み取ることができません。ブラウザコンソールに次のエラーが表示されます

Uncaught(promise)TypeError:「Response」で「json」の実行に失敗しました:本文ストリームがロックされています

返された応答オブジェクトの内容を次のように示しました。

enter image description here

しかし、私はまだ数ヶ月前にそれを使用することができます。

私の質問は次のとおりです。

  • これは単にChromeブラウザの動作ですか、それともフェッチ標準の変更ですか?
  • これらの状態のボディコンテンツを取得する方法はありますか?

PS:ブラウザのバージョンはGoogle Chrome 70.0.3538.102(正式版本)(64位)

39
Luna

Response.clone()を使用してResponseを複製します

fetch('yourfile.json').then(res=>res.clone().json())
33
Criss Anger

私もこのエラーに遭遇しましたが、Responseの状態とは関係がないことがわかりました。実際の問題は、Response.json()を1回しか使用できないことです。複数回使用するとエラーが発生します。

以下のように:

    fetch('http://localhost:3000/movies').then(response =>{
    console.log(response);
    if(response.ok){
         console.log(response.json()); //first consume it in console.log
        return response.json(); //then consume it again, the error happens

    }
32
Wayne Wei

「json」、「text」などの応答メソッドを1回呼び出すと、ロックされます。投稿された応答の画像は、本文がロックされていることを示しています。これは、「then」、「catch」をすでに呼び出していることを意味します。これを再愛するために、次を試すことができます。

fetch(url)
    .then(response=> response.body.json())
    .then(myJson=> console.log(myJson))

または

fetch(url)
    .catch(response=> response.body.json())
    .catch(myJson=> console.log(myJson))
4
Bradia

私もこれにこだわった。しかし、これは私のために働いた。

fetch(YOUR_URL)
.then(res => {
  try {
    if (res.ok) {
      return res.json()
    } else {
      throw new Error(res)
    }
  }
  catch (err) {
    console.log(err.message)
    return WHATEVER_YOU_WANT_TO_RETURN
  }
})
.then (resJson => {
  return resJson.data
})
.catch(err => console.log(err))

幸運を

2
Ankit Kataria

私は誤って応答オブジェクトを再利用していました。これは次のようなものです。

const response = await new ReleasePresetStore().findAll();
const json = await response.json();
this.setState({ releasePresets: json });

const response2 = await new ReleasePresetStore().findActive();
const json2 = await response.json();
this.setState({ active: json2 });
console.log(json2);

この行:

const json2 = await response.json();

あるべきでした(使い古されたresponse1ではなくresponse2):

const json2 = await response2.json();

以前の応答を再利用することは意味がなく、コードのタイプミスでした...

1
Jeremy Bunn