Когда статус запроса больше 400 (я пробовал состояния 400, 423, 429), fetch не может прочитать возвращенное содержимое json. В консоли браузера отображается следующая ошибка
Uncaught (в обещании) TypeError: не удалось выполнить 'json' в 'Response': основной поток заблокирован
Я показал содержимое возвращенного объекта ответа следующим образом:
Но я все еще могу использовать его несколько месяцев назад.
У меня следующий вопрос:
- Это просто поведение браузера Chrome или стандартные изменения выборки?
- Есть ли способ получить содержимое тела этих состояний?
PS: Моя версия браузера - Google Chrome 70.0.3538.102 (正式)) (64 位)
javascript
fetch-api
Луна
источник
источник
Ответы:
Я тоже встречал эту ошибку, но выяснил, что она не связана с состоянием Response, реальная проблема в том, что вы можете потреблять
Response.json()
только один раз, если вы потребляете ее более одного раза, произойдет ошибка.как показано ниже:
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 }
Таким образом, решение - избегать потребления
Response.json()
более одного раза вthen
блоке.источник
response.clone()
прежде чем употреблять его.console.log(r.json()); return r.json();
сломанный.Использовать
Response.clone()
для клонированияResponse
пример
fetch('yourfile.json').then(res=>res.clone().json())
источник
Response.body
, он привязывается к этому читателю. Но из того, что я вижу (по крайней мере, в моем коде), ничего никогда не начиналось читать ... есть ли объяснение того, как читаемый поток может быть автоматически заблокирован?Метод ответа, такой как 'json', 'text', может быть вызван один раз, а затем он блокируется. Опубликованное изображение ответа показывает, что тело заблокировано. Это означает, что вы уже назвали «тогда», «поймать». Чтобы возродить это, вы можете попробовать следующее.
fetch(url) .then(response=> response.body.json()) .then(myJson=> console.log(myJson))
Или
fetch(url) .catch(response=> response.body.json()) .catch(myJson=> console.log(myJson))
источник
Я знаю, что уже поздно, но это может кому-то помочь
let response = await fetch(targetUrl); let data = await response.json();
источник
Я тоже зациклился на этом. Но у меня это сработало.
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))
удачи
источник
Я случайно повторно использовал объект ответа, примерно так:
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();
Должно было быть (response2 вместо использованного response1):
const json2 = await response2.json();
Повторное использование предыдущего ответа не имело смысла, и это была опечатка грязного кода ...
источник
Это сработало для меня
response.json().then(data => { // use data })
источник
Как упоминалось в вопросе, когда вы пытаетесь использовать тот же объект ответа, ваше тело вот-вот заблокируется из-за состояния объекта. Что вы можете сделать, так это захватить значение объекта ответа, а затем попытаться выполнить с ним некоторую операцию (.then ()). Пожалуйста, следуйте приведенному ниже коду,
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 { ---- }) } } }
источник