javascript fetch - не удалось выполнить 'json' для 'Response': поток тела заблокирован

Когда состояние запроса превышает 400 (я пробовал 400, 423, 429 состояний), fetch не может прочитать возвращенный контент json. В консоли браузера отображается следующая ошибка

Uncaught (в обещании) TypeError: Не удалось выполнить 'JSON' на "Ответ": основной поток заблокирован

Я показал содержимое возвращенного объекта ответа следующим образом:

enter image description here

Но я все еще могу использовать его несколько месяцев назад.

Мой вопрос заключается в следующем:

  • Это только поведение браузера Chrome или выборочные изменения стандарта?
  • Есть ли способ получить содержание тела этих состояний?

PS: Моя версия браузера - Google Chrome 70.0.3538.102 (正式 版本) (64 位).

Ответ 1

Используйте Response.clone() чтобы клонировать Response

пример

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

Ответ 2

Я тоже встречал эту ошибку, но обнаружил, что она не связана с состоянием отклика, реальная проблема в том, что вы можете потреблять 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.

Ответ 3

Методы ответа, такие как "json", "текст", можно вызвать один раз, а затем они блокируются. Прикрепленное изображение ответа показывает, что тело заблокировано. Это означает, что вы уже назвали "тогда", "поймать". Чтобы восстановить это, вы можете попробовать следующее.

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

Я случайно повторно использовал объект ответа, что-то похожее на это:

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

Повторное использование предыдущего ответа не имело смысла, и это была грязная опечатка кода...

Ответ 5

Я тоже застрял в этом. Но это сработало для меня.

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

удачи