JavaScript 获取 - 无法在 'Response' 上执行 'json':正文流已锁定

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

当请求状态大于400(我试过400、423、429状态)时,fetch无法读取返回的json内容。浏览器控制台显示如下错误

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

我展示了返回的响应对象内容如下:

不过几个月前还能用

我的问题如下:

PS: 我的浏览器版本是Google Chrome 70.0.3538.102(正式版本)(64位)

根据 MDN,您应该使用 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.)

例子:

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

我也遇到这个错误,但发现它与Response的状态无关,真正的问题是你只能消费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

    }

所以解决方案是避免在 then 块中多次使用 Response.json()

像'json'、'text'这样的响应方法可以调用一次,然后就锁定了。 发布的响应图像显示 body 已锁定。 这意味着您已经调用了'then'、'catch'。要解决此问题,您可以尝试以下操作。

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

或者

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

我不小心重用了一个响应对象,类似于:

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

重复使用之前的响应没有任何意义,这是一个肮脏的代码错字...

我也深陷其中。但这对我有用。

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

祝你好运

如问题中所述,当您尝试使用相同的响应 object 时,由于 object 的状态,您的 body 即将被锁定。您可以做的是捕获响应 object 的值,然后尝试对其进行一些操作 (.then())。请按照下面的代码,

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

这对我有用

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

我知道为时已晚,但它可以帮助某人:

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

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