javascript fetch - 无法在“响应”上执行“json”:正文流已锁定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53511974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:07:51  来源:igfitidea点击:

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

javascriptfetch-api

提问by Luna

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

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

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

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?
  • 这只是 Chrome 浏览器的行为还是获取标准的变化?
  • 有没有办法获得这些状态的正文内容?

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

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

回答by Wayne Wei

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.

我也遇到了这个错误,但发现它与 Response 的状态无关,真正的问题是您只能消费Response.json()一次,如果您多次消费,就会发生错误。

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 thenblock.

所以解决方案是避免Response.json()then块中消耗超过一次。

回答by Criss Anger

Use Response.clone()to clone Response

使用Response.clone()到克隆Response

example

例子

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

回答by Bradia

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.

'json'、'text' 之类的响应方法可以调用一次,然后锁定。发布的响应图像显示正文已锁定。这意味着您已经调用了“then”、“catch”。要重新喜欢它,您可以尝试以下操作。

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

回答by Jeremy Bunn

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

应该是(response2 而不是用完的 response1):

const json2 = await response2.json();

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

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

回答by Ankit Kataria

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

祝你好运

回答by Beau Barker

This worked for me

这对我有用

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

回答by cherif

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

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

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

回答by Juhil Somaiya

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,

正如问题中提到的,当您尝试使用相同的响应对象时,由于对象的状态,您的身体即将锁定。您可以做的是捕获响应对象的值,然后尝试对其进行一些操作(.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 { ---- })
        }
    } 
}