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

Luna
fonte
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.

Wayne Wei
fonte
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())
Criss Anger
fonte
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))
Bradia
fonte
3

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

let response = await fetch(targetUrl);
let data = await response.json();
Cherif
fonte
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

Ankit Kataria
fonte
Um exemplo sobre busca no MDN github.com/mdn/fetch-examples/blob/master/fetch-json/…
Magaesh
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 ...

Jeremy Bunn
fonte
1

Isso funcionou para mim

response.json().then(data => {
  // use data
})
Beau Barker
fonte
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 { ---- })
        }
    } 
}
Juhil Somaiya
fonte