Gdy stan żądania jest większy niż 400 (próbowałem 400, 423, 429 stanów), funkcja pobierania nie może odczytać zwróconej zawartości json. Następujący błąd jest wyświetlany w konsoli przeglądarki
Uncatcht (in promise) TypeError: Failed to execute „json” on „Response”: body stream jest zablokowane
Zawartość zwróconego obiektu odpowiedzi pokazałem następująco:
Ale mogę go używać jeszcze kilka miesięcy temu.
Moje pytanie brzmi następująco:
- Czy to tylko zachowanie przeglądarki Chrome, czy standardowe zmiany pobierania?
- Czy istnieje sposób, aby uzyskać zawartość ciała w tych stanach?
PS: Wersja mojej przeglądarki to Google Chrome 70.0.3538.102 (正式 版本) (64 位)
javascript
fetch-api
Luna
źródło
źródło
Odpowiedzi:
Spotkałem też ten błąd, ale okazało się, że nie jest to związane ze stanem odpowiedzi, prawdziwy problem polega na tym, że możesz skonsumować tylko
Response.json()
raz, jeśli zużyjesz go więcej niż raz, błąd się wydarzy.jak poniżej:
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 }
Więc rozwiązaniem jest unikanie spożywania
Response.json()
więcej niż raz wthen
bloku.źródło
response.clone()
przed spożyciem.console.log(r.json()); return r.json();
który go zepsuł.Służy
Response.clone()
do klonowaniaResponse
przykład
fetch('yourfile.json').then(res=>res.clone().json())
źródło
Response.body
, zostaje on zablokowany. Ale z tego, co widzę (przynajmniej w moim kodzie), nic nie zaczęło się czytać ... czy istnieje wyjaśnienie, w jaki sposób czytelny strumień może zostać automatycznie zablokowany?Metodę odpowiedzi, taką jak „json”, „tekst” można wywołać raz, a następnie blokuje. Opublikowany obraz odpowiedzi pokazuje, że treść jest zablokowana. Oznacza to, że już zadzwoniłeś do „wtedy”, „złap”. Aby rozwiązać ten problem, możesz spróbować wykonać następujące czynności.
fetch(url) .then(response=> response.body.json()) .then(myJson=> console.log(myJson))
Lub
fetch(url) .catch(response=> response.body.json()) .catch(myJson=> console.log(myJson))
źródło
Wiem, że jest za późno, ale może komuś pomóc:
let response = await fetch(targetUrl); let data = await response.json();
źródło
Ja też się w to utknąłem. Ale to zadziałało dla mnie.
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))
powodzenia
źródło
Przypadkowo ponownie użyłem obiektu odpowiedzi, coś podobnego do tego:
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);
Ta linia:
const json2 = await response.json();
Powinno być (odpowiedź2 zamiast zużytej odpowiedzi1):
const json2 = await response2.json();
Ponowne użycie poprzedniej odpowiedzi nie miało sensu i była to brudna literówka ...
źródło
To zadziałało dla mnie
response.json().then(data => { // use data })
źródło
Jak wspomniano w pytaniu, gdy próbujesz użyć tego samego obiektu odpowiedzi, twoje ciało zostanie zablokowane z powodu stanu obiektu. To, co możesz zrobić, to przechwycić wartość obiektu odpowiedzi, a następnie spróbować wykonać na nim jakąś operację (.then ()). Postępuj zgodnie z poniższym kodem,
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 { ---- }) } } }
źródło