获取时出错
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将返回
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);