使用 Promise.all() 和 put 方法获取时 JSON 输入意外结束
Unexpected end of JSON input when using Promise.all() and put method in fetch
我在使用 Javascript 时遇到问题,当时我尝试从 API 获取邮件内容并同时更新其阅读状态。控制台中的错误信息是:
SyntaxError: Unexpected end of JSON input
at inbox.js:98
日志中的错误承诺如下。
1: Promise
[[Prototype]]: Promise
[[PromiseState]]: "rejected"
[[PromiseResult]]: SyntaxError: Unexpected end of JSON input at http://127.0.0.1:8000/static/mail/inbox.js:98:30
message: "Unexpected end of JSON input"
stack: "SyntaxError: Unexpected end of JSON input\n at http://127.0.0.1:8000/static/mail/inbox.js:98:30"
第 98 行的代码是:
let res2 = response[1].json();
完整的js代码如下。我检查了名为 res1
和 res2
的承诺。看来问题出在res2
,因为它的return是rejected
。我尝试了不同的方法来解决它,但都失败了。我也不明白为什么它没有被 catch
函数捕获。提前谢谢你。
虽然它每次 returns SyntaxError
。 fetch
两个函数都已经工作了...
async function show_single_mail(email_id){
// Show content of selected email
document.querySelector('#mails_table').style.display = 'none';
const email_div = document.createElement('div');
document.querySelector('#emails-view').append(email_div);
// Obtain email content and update its read status concurrently
const option2 = {
method: 'PUT',
body: JSON.stringify({read: true})}
Promise.all([fetch(`/emails/${email_id}`), fetch(`/emails/${email_id}`, option2)])
.then(response => {
let res1 = response[0].json();
let res2 = response[1].json();
console.log([res1, res2]);
return Promise.all([res1, res2])
})
.then(results => {
result = results[0];
email_div.innerHTML =
`<h3>Subject: ${result.subject}</h3><br>` +
`<p>Sender: ${result.sender}</p><br>`+
`<p>Receiver: ${result.recipients}</p><br>`+
`<p>Time: ${result.timestamp}</p><br>`+
`<p>Content: ${result.body}</p>`;
})
.catch(err => console.log(err))
}
您正在使用
执行两个并行请求
Promise.all([fetch(...), fetch(...)])
很好。但是当你处理你的结果时,你并没有检查请求是否成功,并且 fetch
不会拒绝 4xx 状态代码。此外,对于不成功的请求,您的服务器显然不会 return JSON 而只是文本。甚至可能是,第二个请求成功,但没有有效的 json 正文。没有人知道你的 API 到底是做什么的。
当你现在做的时候
.then(responses => {
responses[0].json(); //this response has a valid json body
responses[1].json(); //this one doesn't
})
response[1]
的正文无法解析为 json(responses[1].json()
试图这样做)。因此,抛出一个错误。所以你必须先检查一下,如果你的请求是 successful/returned json,然后你才能阅读他们的正文
.then(responses => {
let s = responses.filter(x => x.ok); //status == 2xx
let f = responses.filter(x => !x.ok); //status != 2xx
//do something with failed requests and
//only read the body for successful responses
//return Promise.all(s.map(x => x.json());
//or try to read json for successful and text for unsuccessful responsees
//return Promise.all(responses.map(r => r.ok ? r.json() : r.text()));
//or try to check the contenttype of the responses (if the server correctly sets them
//return Promise.all(responses.map(r => r.headers.get("content-type").includes("application/json")
// ? res.json()
// : res.text()
// ));
})
.then(responses => {
//display them
});
我在使用 Javascript 时遇到问题,当时我尝试从 API 获取邮件内容并同时更新其阅读状态。控制台中的错误信息是:
SyntaxError: Unexpected end of JSON input
at inbox.js:98
日志中的错误承诺如下。
1: Promise
[[Prototype]]: Promise
[[PromiseState]]: "rejected"
[[PromiseResult]]: SyntaxError: Unexpected end of JSON input at http://127.0.0.1:8000/static/mail/inbox.js:98:30
message: "Unexpected end of JSON input"
stack: "SyntaxError: Unexpected end of JSON input\n at http://127.0.0.1:8000/static/mail/inbox.js:98:30"
第 98 行的代码是:
let res2 = response[1].json();
完整的js代码如下。我检查了名为 res1
和 res2
的承诺。看来问题出在res2
,因为它的return是rejected
。我尝试了不同的方法来解决它,但都失败了。我也不明白为什么它没有被 catch
函数捕获。提前谢谢你。
虽然它每次 returns SyntaxError
。 fetch
两个函数都已经工作了...
async function show_single_mail(email_id){
// Show content of selected email
document.querySelector('#mails_table').style.display = 'none';
const email_div = document.createElement('div');
document.querySelector('#emails-view').append(email_div);
// Obtain email content and update its read status concurrently
const option2 = {
method: 'PUT',
body: JSON.stringify({read: true})}
Promise.all([fetch(`/emails/${email_id}`), fetch(`/emails/${email_id}`, option2)])
.then(response => {
let res1 = response[0].json();
let res2 = response[1].json();
console.log([res1, res2]);
return Promise.all([res1, res2])
})
.then(results => {
result = results[0];
email_div.innerHTML =
`<h3>Subject: ${result.subject}</h3><br>` +
`<p>Sender: ${result.sender}</p><br>`+
`<p>Receiver: ${result.recipients}</p><br>`+
`<p>Time: ${result.timestamp}</p><br>`+
`<p>Content: ${result.body}</p>`;
})
.catch(err => console.log(err))
}
您正在使用
执行两个并行请求Promise.all([fetch(...), fetch(...)])
很好。但是当你处理你的结果时,你并没有检查请求是否成功,并且 fetch
不会拒绝 4xx 状态代码。此外,对于不成功的请求,您的服务器显然不会 return JSON 而只是文本。甚至可能是,第二个请求成功,但没有有效的 json 正文。没有人知道你的 API 到底是做什么的。
当你现在做的时候
.then(responses => {
responses[0].json(); //this response has a valid json body
responses[1].json(); //this one doesn't
})
response[1]
的正文无法解析为 json(responses[1].json()
试图这样做)。因此,抛出一个错误。所以你必须先检查一下,如果你的请求是 successful/returned json,然后你才能阅读他们的正文
.then(responses => {
let s = responses.filter(x => x.ok); //status == 2xx
let f = responses.filter(x => !x.ok); //status != 2xx
//do something with failed requests and
//only read the body for successful responses
//return Promise.all(s.map(x => x.json());
//or try to read json for successful and text for unsuccessful responsees
//return Promise.all(responses.map(r => r.ok ? r.json() : r.text()));
//or try to check the contenttype of the responses (if the server correctly sets them
//return Promise.all(responses.map(r => r.headers.get("content-type").includes("application/json")
// ? res.json()
// : res.text()
// ));
})
.then(responses => {
//display them
});