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

JavascriptFetch Api

Javascript Problem Overview


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

Javascript Solutions


Solution 1 - Javascript

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 2 - Javascript

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 3 - Javascript

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

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

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

Solution 5 - Javascript

I was accidentally reusing a response object, something similar to this:

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

This line:

const json2 = await response.json();

Should have been (response2 instead of the used up response1):

const json2 = await response2.json();

Reusing the previous response made no sense and it was a dirty code typo...

Solution 6 - Javascript

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

Solution 7 - Javascript

This worked for me

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

Solution 8 - Javascript

fetch("xxxxxxxxxx")
.then(response => response.json())
.then(data => { console.log(data)})
.catch(error => { console.log(error)})

Solution 9 - Javascript

As mentioned in the question when you're trying to use same response object, your body is about to locked due to state of the object. What you can do is that capture the value of the response object and then try to have some operation on it (.then()). Please follow the code below,

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLunaView Question on Stackoverflow
Solution 1 - JavascriptWayne WeiView Answer on Stackoverflow
Solution 2 - JavascriptCriss AngerView Answer on Stackoverflow
Solution 3 - JavascriptBradiaView Answer on Stackoverflow
Solution 4 - JavascriptcherifView Answer on Stackoverflow
Solution 5 - JavascriptJeremy BunnView Answer on Stackoverflow
Solution 6 - JavascriptAnkit KatariaView Answer on Stackoverflow
Solution 7 - JavascriptBeau BarkerView Answer on Stackoverflow
Solution 8 - JavascriptKrutik RautView Answer on Stackoverflow
Solution 9 - JavascriptJuhil SomaiyaView Answer on Stackoverflow