pengambilan javascript - Gagal mengeksekusi 'json' pada 'Respon': aliran tubuh dikunci


112

Ketika status permintaan lebih besar dari 400 (saya telah mencoba 400, 423, 429 negara bagian), pengambilan tidak dapat membaca konten json yang dikembalikan. Kesalahan berikut ini ditampilkan di konsol browser

Tidak tertangkap (dalam janji) TypeError: Gagal mengeksekusi 'json' pada 'Respon': aliran tubuh terkunci

Saya menunjukkan konten objek respons yang dikembalikan sebagai berikut:

masukkan deskripsi gambar di sini

Tapi saya masih bisa menggunakannya beberapa bulan yang lalu.

Pertanyaan saya adalah sebagai berikut:

  • Apakah ini hanya perilaku browser Chrome atau perubahan standar pengambilan?
  • Adakah cara untuk mendapatkan isi tubuh dari keadaan ini?

PS: Versi browser saya adalah Google Chrome 70.0.3538.102 (正式 版本) (64 位)


Ini berarti Anda mendapatkan respons dari api, tetapi ini bukan json yang valid, apakah Anda mengirim semua parameter yang diperlukan dalam permintaan?
kiranvj

@kiranvj Saya memverifikasi data saya, konten yang sama, saya baru saja mengubah kode status menjadi 200 untuk mendapatkannya dengan benar.
Luna

1
Saya memiliki masalah yang sama tetapi status saya 200, bagaimana Anda menyelesaikannya pada akhirnya?
DavSev

@DavSev Untuk kode status tertentu, saya mendapatkan data pengembalian melalui aksios
Luna

1
itu terjadi dengan 200 juga.
schlingel

Jawaban:


182

Saya menemui kesalahan ini juga tetapi ternyata itu tidak terkait dengan status Respon, masalah sebenarnya adalah Anda hanya dapat mengkonsumsi Response.json()sekali, jika Anda mengkonsumsinya lebih dari sekali, kesalahan akan terjadi.

seperti dibawah ini:

    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

    }

Jadi solusinya adalah hindari mengkonsumsi Response.json()lebih dari sekali dalam thenblok.


6
Anda bisa response.clone()sebelum mengonsumsinya.
balduran

Bagus. Saya punya console.log(r.json()); return r.json();yang memecahkannya.
mewc

2
Terima kasih itu berhasil untuk saya ..... adakah yang bisa menjelaskan perilaku aneh ini?
Sachin

Terima kasih, kawan, ini bekerja dengan sempurna untuk saya
Ronny Perez

75

Gunakan Response.clone()untuk mengkloningResponse

contoh

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

19
Ini bekerja dengan baik untuk saya, tetapi ada yang mengerti mengapa ini perlu? saya mencarinya, dan saya melihat bahwa kadang-kadang begitu seorang pembaca mulai membaca Response.body, itu terkunci pada pembaca itu. Tetapi dari apa yang dapat saya lihat (setidaknya dalam kode saya), tidak ada yang mulai membaca ... apakah ada penjelasan tentang bagaimana aliran yang dapat dibaca dapat terkunci secara otomatis?
jenming

6
Saya memiliki masalah yang sama tetapi ternyata saya memiliki "res.json ()" di panel jam tangan saya di alat dev chrome, yang diselesaikan sebelum kode itu sendiri!
FelipeDrumond

1
tunggu apa? @FelipeDrumond itu bug gila (non)!
George Mauer

@GeorgeMauer Nah, jika kita hanya dapat menjalankan response.json () sekali dan panel arloji alat dev chrome Anda menjalankannya sebelum kode Anda, Anda akan memiliki pengecualian karena Anda menjalankan response.json () dua kali!
FelipeDrumond

Referensi MDN
foxiris

8

Metode respon seperti 'json', 'teks' dapat dipanggil sekali, dan kemudian terkunci. Gambar tanggapan yang diposting menunjukkan bahwa badan terkunci. Ini berarti Anda telah memanggil 'kemudian', 'menangkap'. Untuk mengatasi ini, Anda dapat mencoba yang berikut ini.

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

Atau

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

4

Saya tahu ini sudah terlambat tetapi ini dapat membantu seseorang:

let response = await fetch(targetUrl);
let data = await response.json();

Persis yang saya butuhkan untuk menyelesaikan masalah ini menggunakan sintaks async / await, terima kasih!
ttemple

2

Saya juga terjebak dalam hal ini. Tapi ini berhasil untuk saya.

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))

semoga berhasil



1

Saya tidak sengaja menggunakan kembali objek respons, mirip dengan ini:

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);

Garis ini:

const json2 = await response.json();

Seharusnya (respon2 bukannya digunakan respon1):

const json2 = await response2.json();

Menggunakan kembali respons sebelumnya tidak masuk akal dan itu adalah kesalahan ketik kode kotor ...


1

Ini berhasil untuk saya

response.json().then(data => {
  // use data
})

0

Seperti yang disebutkan dalam pertanyaan ketika Anda mencoba menggunakan objek respons yang sama, tubuh Anda akan segera terkunci karena keadaan objek tersebut. Apa yang dapat Anda lakukan adalah menangkap nilai objek respons dan kemudian mencoba melakukan beberapa operasi padanya (.then ()). Silakan ikuti kode di bawah ini,

fetch('someurl').then(respose) => {
    let somedata = response.json(); // as you will capture the json response, body will not be locked anymore. 
    somedata.then(data) => {
        {
             error handling (if (data.err) { ---- })
        }
        {
             operations (else { ---- })
        }
    } 
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.