JavaScript fetch - Failed to execute 'json' on 'Response': body stream is locked

106,276

Solution 1

According to MDN, you should use Response.clone():

The clone() method of the Response interface creates a clone of a response object, identical in every way, but stored in a different variable. The main reason clone() exists is to allow multiple uses of Body objects (when they are one-use only.)

Example:

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

Solution 2

I met this error too but found out it is not related to the state of Response, the real problem is that you only can consume Response.json() once, if you are consuming it more than once, the error will happen.

like below:

    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

    }

So the solution is to avoid consuming Response.json() more than once in then block.

Solution 3

Response methode like 'json', 'text' can be called once, and then it locks. The posted image of response shows that body is locked. This means you have already called the 'then', 'catch'. To reslove this you can try the following.

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

Or

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

Solution 4

I know it's too late but it can help someone:

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

Solution 5

I also stuck into this. But this worked for me.

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

good luck

Share:
106,276
Luna
Author by

Luna

Like code

Updated on May 13, 2021

Comments

  • Luna
    Luna over 2 years

    When the request status is greater than 400(I have tried 400, 423, 429 states), fetch cannot read the returned json content. The following error is displayed in the browser console

    Uncaught (in promise) TypeError: Failed to execute 'json' on 'Response': body stream is locked

    I showed the contents of the returned response object as follows:

    enter image description here

    But I can still use it a few months ago.

    My question is as follows:

    • Is this just the behavior of the Chrome browser or the fetch standard changes?
    • Is there any way to get the body content of these states?

    PS: My browser version is Google Chrome 70.0.3538.102(正式版本) (64 位)

  • jenming
    jenming almost 5 years
    This worked great for me, but anyone understand why this is necessary? i looked it up, and I see that sometimes once a reader starts reading the Response.body, it gets locked to that reader. But from what I can see (at least in my code), nothing has ever started reading... is there an explanation of how the readable stream could get automatically locked?
  • FelipeDrumond
    FelipeDrumond over 4 years
    I had the same issue but found out that I had "res.json()" in my watch panel in chrome dev tools, which was being resolved before the code itself!
  • Magaesh
    Magaesh about 4 years
  • Abhishek
    Abhishek about 4 years
    wait, what? @FelipeDrumond thats a crazy (non) bug!
  • FelipeDrumond
    FelipeDrumond about 4 years
    @GeorgeMauer Well, if we can only run response.json() once and your chrome dev tools watch panel runs that before your code, you'll have an exception because well, you ran response.json() twice!
  • foxiris
    foxiris almost 4 years
    Reference MDN
  • balduran
    balduran over 3 years
    you could response.clone() before consuming it.
  • mewc
    mewc over 3 years
    Nice. i had a console.log(r.json()); return r.json(); which broke it.
  • Sachin
    Sachin over 3 years
    Thanks it worked for me.....can anyone explain this weird behaviour?
  • ttemple
    ttemple about 3 years
    Exactly what I needed to resolve this matter using async/await syntax, thank you!
  • msbit
    msbit over 2 years
    Unsure if this has changed since 2019, but now calling Response.clone() in the original question scenario (when Response.body.locked is true) throws a TypeError (e.g TypeError: Response.clone: Body has already been consumed.). As per MDN: clone() throws a TypeError if the response Body has already been used
  • Saveen
    Saveen over 2 years
    very nice!! I was also doing the same mistake console.log(response.json()); return response.json()
  • Alexander Matveev
    Alexander Matveev about 2 years
    If response is not in JSON format, you'll be locked