javascript getirme - "Yanıt" üzerinde "json" yürütülemedi: gövde akışı kilitlendi


113

İstek durumu 400'den büyük olduğunda (400, 423, 429 durumlarını denedim), getirme döndürülen json içeriğini okuyamıyor. Tarayıcı konsolunda aşağıdaki hata görüntüleniyor

Yakalanmamış (sözde) TypeError: "Yanıt" üzerinde "json" yürütülemedi: gövde akışı kilitlendi

Döndürülen yanıt nesnesinin içeriğini aşağıdaki gibi gösterdim:

görüntü açıklamasını buraya girin

Ama yine de birkaç ay önce kullanabilirim.

Sorum şu:

  • Bu sadece Chrome tarayıcısının davranışı mı yoksa getirme standart değişiklikleri mi?
  • Bu durumların vücut içeriğini almanın bir yolu var mı?

Not: Tarayıcı sürümüm Google Chrome 70.0.3538.102 (正式 版本) (64 位)


Bu, api'den bir yanıt aldığınız anlamına gelir, ancak bu geçerli bir json değildir, istekte gerekli tüm parametreleri gönderiyor musunuz?
kiranvj

@kiranvj Verilerimi, aynı içeriği doğruladım, doğru bir şekilde almak için durum kodunu 200 olarak değiştirdim.
Luna

1
Bende de aynı sorun var ama durumum 200, sonunda nasıl çözdün?
DavSev

@DavSev Belirli bir durum kodu için, dönüş verilerini axios üzerinden alıyorum
Luna

1
200 ile de olur.
schlingel

Yanıtlar:


184

Ben de bu hatayla karşılaştım ancak bunun Yanıt durumuyla ilgili olmadığını öğrendim, asıl sorun yalnızca tüketebileceğiniz Response.json() kez , birden fazla tüketiyorsanız hata oluşacak.

aşağıdaki gibi:

    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

    }

Dolayısıyla çözüm, blokta Response.json()birden fazla tüketmekten kaçınmaktır then.


6
response.clone()tüketmeden önce yapabilirsin .
balduran

Güzel. console.log(r.json()); return r.json();kırdı bir tane vardı .
mewc

2
Teşekkürler, benim için çalıştı ..... bu garip davranışı kimse açıklayabilir mi?
Sachin

78

Kullanım Response.clone() içinResponse

misal

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

21
Bu benim için harika çalıştı, ancak bunun neden gerekli olduğunu anlayan var mı? baktım ve bazen bir okuyucu okumaya başladığında Response.body, o okuyucuya kilitlendiğini görüyorum . Ama görebildiğim kadarıyla (en azından benim kodumda), hiçbir şey okumaya başlamadı ... Okunabilir akışın otomatik olarak nasıl kilitlenebileceğine dair bir açıklama var mı?
jenming

6
Aynı sorunu yaşadım ancak krom dev araçlarındaki izleme panelimde "res.json ()" olduğunu öğrendim, bu kodun kendisinden önce çözülüyordu!
FelipeDrumond

1
bir dakika ne? @FelipeDrumond bu çılgın (olmayan) bir hata!
George Mauer

@GeorgeMauer Evet, response.json () işlevini yalnızca bir kez çalıştırabilirsek ve chrome dev araçları izleme paneliniz bunu kodunuzdan önce çalıştırırsa, bir istisnanız olur çünkü iyi, response.json () öğesini iki kez çalıştırdınız!
FelipeDrumond

Referans MDN
foxiris

9

'Json', 'metin' gibi yanıt yöntemleri bir kez çağrılabilir ve ardından kilitlenir. Gönderilen yanıt resmi, vücudun kilitlendiğini gösterir. Bu, zaten "o zaman", "yakala" dediğiniz anlamına gelir. Bunu yeniden yaşamak için aşağıdakileri deneyebilirsiniz.

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

Veya

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

4

Çok geç olduğunu biliyorum ama birine yardımcı olabilir:

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

Bu sorunu eşzamansız / bekleme sözdizimi kullanarak çözmek için tam olarak ihtiyacım olan şey, teşekkür ederim!
ttemple


1

Yanlışlıkla bir yanıt nesnesini yeniden kullanıyordum, buna benzer bir şey:

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

Bu hat:

const json2 = await response.json();

Olmalıydı (kullanılmış yanıt1 yerine yanıt2):

const json2 = await response2.json();

Önceki yanıtı tekrar kullanmak anlamsızdı ve kirli bir kod yazım hatasıydı ...


1

Bu benim için çalıştı

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

0

Aynı yanıt nesnesini kullanmaya çalıştığınızda soruda da belirtildiği gibi, nesnenin durumu nedeniyle vücudunuz kilitlenmek üzeredir. Yapabileceğiniz şey, yanıt nesnesinin değerini yakalamak ve ardından üzerinde bir işlem yapmaktır (.then ()). Lütfen aşağıdaki kodu takip edin,

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 { ---- })
        }
    } 
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.