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
我展示了返回的响应对象内容如下:
不过几个月前还能用
我的问题如下:
- 这只是 Chrome 浏览器的行为还是抓取标准发生了变化?
- 有没有办法获取这些状态的body内容?
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)})
当请求状态大于400(我试过400、423、429状态)时,fetch无法读取返回的json内容。浏览器控制台显示如下错误
Uncaught (in promise) TypeError: Failed to execute 'json' on 'Response': body stream is locked
我展示了返回的响应对象内容如下:
不过几个月前还能用
我的问题如下:
- 这只是 Chrome 浏览器的行为还是抓取标准发生了变化?
- 有没有办法获取这些状态的body内容?
PS: 我的浏览器版本是Google Chrome 70.0.3538.102(正式版本)(64位)
根据 MDN,您应该使用 Response.clone()
:
The
clone()
method of theResponse
interface creates a clone of a response object, identical in every way, but stored in a different variable. The main reasonclone()
exists is to allow multiple uses ofBody
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)})