UnhandledPromiseRejectionWarning: FetchError: invalid json response body at
UnhandledPromiseRejectionWarning: FetchError: invalid json response body at
获取错误:
UnhandledPromiseRejectionWarning: FetchError: invalid json response body at {url}
reason: Unexpected token < in JSON at position 0
我的代码:
const fetch = require('node-fetch');
const url = 'Reeeealy long url here';
fetch(url)
.then(res => res.json())
.then(console.log);
如果 url 长于 ~8k+ 个字符 api returns
400 Bad Request
Request Header Or Cookie Too Large
nginx
显然我无法控制 api。
我能做些什么来防止这种情况发生?
url结构:
1) 域
2) api 版本
3) 端点
4) 请求内容(最长的部分)
5) id在最后
看起来像这样:https://example.com/v1/endpoint/query?query=long_part_here&ids=2145132,532532,535
如果预期 'long_part' 很长,这听起来像是设计不佳的 api。它应该使用 POST
而不是 GET
请求,以便可以在 body
对象中发送长数据集。你能看到 API 是否允许 POST 版本的端点允许吗?
如果没有 POST
可用,并且您无法控制 API,那么您的选择余地不大。我唯一能想到的是,如果可行的话,您将请求分成多个单独的端点调用(可能每个 id
一个),并且会导致每个请求的 url
大小更短。
多次调用
如果您能够执行多个较小的请求,代码可能如下所示:
const urls = ["firstUrl","secondUrl","nthUrl"];
let combined = {};
for (const url of urls) {
fetch(url)
.then(res => res.json())
.then(json => combined = {...combined, ...json};
}
console.log(combined);
这假定将所有结果合并到一个对象中是合理的。如果它们应该保持不同,您可以像这样更改最后一个 then
:
.then(json => combined = {...combined, {`url${count}`: json}};
其中 count
是每次递增的整数,combined
看起来像
{url1: {/*json from url1*/}, url2: {/*json from url2*/}, ...}
错误处理
为了更优雅地处理错误,您应该在假设返回结果之前检查结果 JSON
。您遇到了 JSON
解析错误,因为返回的数据不是 JSON
。它是 HTML
,所以当它以 <
开始时失败了。你可以这样做:
fetch(url)
.then(res => {
if (res.resultCode == "200") return res.json();
return Promise.reject(`Bad call: ${res.resultCode}`);
})
.then(console.log);
获取错误:
UnhandledPromiseRejectionWarning: FetchError: invalid json response body at {url}
reason: Unexpected token < in JSON at position 0
我的代码:
const fetch = require('node-fetch');
const url = 'Reeeealy long url here';
fetch(url)
.then(res => res.json())
.then(console.log);
如果 url 长于 ~8k+ 个字符 api returns
400 Bad Request
Request Header Or Cookie Too Large
nginx
显然我无法控制 api。
我能做些什么来防止这种情况发生?
url结构:
1) 域
2) api 版本
3) 端点
4) 请求内容(最长的部分)
5) id在最后
看起来像这样:https://example.com/v1/endpoint/query?query=long_part_here&ids=2145132,532532,535
如果预期 'long_part' 很长,这听起来像是设计不佳的 api。它应该使用 POST
而不是 GET
请求,以便可以在 body
对象中发送长数据集。你能看到 API 是否允许 POST 版本的端点允许吗?
如果没有 POST
可用,并且您无法控制 API,那么您的选择余地不大。我唯一能想到的是,如果可行的话,您将请求分成多个单独的端点调用(可能每个 id
一个),并且会导致每个请求的 url
大小更短。
多次调用
如果您能够执行多个较小的请求,代码可能如下所示:
const urls = ["firstUrl","secondUrl","nthUrl"];
let combined = {};
for (const url of urls) {
fetch(url)
.then(res => res.json())
.then(json => combined = {...combined, ...json};
}
console.log(combined);
这假定将所有结果合并到一个对象中是合理的。如果它们应该保持不同,您可以像这样更改最后一个 then
:
.then(json => combined = {...combined, {`url${count}`: json}};
其中 count
是每次递增的整数,combined
看起来像
{url1: {/*json from url1*/}, url2: {/*json from url2*/}, ...}
错误处理
为了更优雅地处理错误,您应该在假设返回结果之前检查结果 JSON
。您遇到了 JSON
解析错误,因为返回的数据不是 JSON
。它是 HTML
,所以当它以 <
开始时失败了。你可以这样做:
fetch(url)
.then(res => {
if (res.resultCode == "200") return res.json();
return Promise.reject(`Bad call: ${res.resultCode}`);
})
.then(console.log);