busca de javascript - Falha ao executar 'json' em 'Resposta': o fluxo do corpo está bloqueado


106

Quando o status da solicitação é superior a 400 (tentei 400, 423, 429 estados), a busca não pode ler o conteúdo json retornado. O seguinte erro é exibido no console do navegador

Não capturado (em promessa) TypeError: Falha ao executar 'json' em 'Resposta': fluxo de corpo está bloqueado

Mostrei o conteúdo do objeto de resposta retornado da seguinte maneira:

insira a descrição da imagem aqui

Mas ainda posso usar há alguns meses.

Minha pergunta é a seguinte:

  • É apenas o comportamento do navegador Chrome ou as alterações do padrão de busca?
  • Existe alguma maneira de obter o conteúdo corporal desses estados?

PS: a versão do meu navegador é Google Chrome 70.0.3538.102 (正式 版本) (64 位)


Isso significa que você está recebendo uma resposta da api, mas não é um json válido. Você está enviando todos os parâmetros necessários na solicitação?
— kiranvj

@kiranvj Eu verifiquei meus dados, o mesmo conteúdo, apenas alterei o código de status para 200 para obtê-lo corretamente.
— Luna

1
Eu tenho o mesmo problema, mas meu status é 200, como você resolveu isso eventualmente?
— DavSev

@DavSev Para um código de status específico, obtenho os dados de retorno por meio de axios
— Luna

1
isso acontece com 200 também.
— Schlingel

Respostas:


173

Encontrei esse erro também mas descobri que não está relacionado ao estado de Response, o verdadeiro problema é que você só pode consumir Response.json()uma vez, se estiver consumindo mais de uma vez, o erro vai acontecer.

como abaixo:

    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

    }

Portanto, a solução é evitar consumir Response.json()mais de uma vez em thenbloco.


4
você poderia response.clone()antes de consumir.
— Balduran

Agradável. Eu tive um console.log(r.json()); return r.json();que quebrou.
— mewc,

2
Obrigado, funcionou para mim ... alguém pode explicar esse comportamento estranho?
— Sachin,

72

Use Response.clone()para clonarResponse

exemplo

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

18
Isso funcionou muito bem para mim, mas alguém entende por que isso é necessário? Eu pesquisei e vejo que às vezes, quando um leitor começa a ler o Response.body, ele fica preso a esse leitor. Mas pelo que posso ver (pelo menos no meu código), nada começou a ser lido ... há uma explicação de como o fluxo legível pode ser bloqueado automaticamente?
— jenming

5
Eu tive o mesmo problema, mas descobri que tinha "res.json ()" em meu painel de observação nas ferramentas de desenvolvimento do Chrome, que estava sendo resolvido antes do próprio código!
— FelipeDrumond

1
espere o que? @FelipeDrumond isso é um bug maluco (não)!
— George Mauer

@GeorgeMauer Bem, se pudermos executar response.json () apenas uma vez e seu painel de observação de ferramentas de desenvolvimento do Chrome executar isso antes de seu código, você terá uma exceção porque bem, você executou response.json () duas vezes!
— FelipeDrumond

Referência MDN
— foxiris

7

O método de resposta como 'json', 'texto' pode ser chamado uma vez e, em seguida, é bloqueado. A imagem de resposta postada mostra que o corpo está bloqueado. Isso significa que você já chamou o 'então', 'pegar'. Para resolver isso, você pode tentar o seguinte.

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

Ou

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

3

Eu sei que é tarde demais, mas pode ajudar alguém:

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

2

Eu também me empenhei nisso. Mas isso funcionou para mim.

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

boa sorte



1

Eu estava reutilizando acidentalmente um objeto de resposta, algo semelhante a isto:

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

Está linha:

const json2 = await response.json();

Deveria ter sido (resposta2 em vez da resposta usada 1):

const json2 = await response2.json();

Reutilizar a resposta anterior não fazia sentido e era um erro de digitação de código ...


1

Isso funcionou para mim

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

0

Conforme mencionado na pergunta, quando você está tentando usar o mesmo objeto de resposta, seu corpo está prestes a travar devido ao estado do objeto. O que você pode fazer é capturar o valor do objeto de resposta e, em seguida, tentar fazer alguma operação nele (.então ()). Siga o código abaixo,

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 { ---- })
        }
    } 
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.