如何解决Apollo REST 数据源和 Imgur API - 使用表单数据不断收到 400 个错误请求
我正在尝试通过 Imgur 的 API 实现 apollo-datasource-rest
来处理通过 URL 上传的图片(文档在这里:https://apidocs.imgur.com/)
我最初收到一个 400
错误,它读取 We don't support that file type!
,并确定这是由于 apollo-datasource-rest
自动将 Content-Type
设置为 application/json
。使用 form-data
npm 包修复该问题后,我的代码如下所示:
class ImgurAPI extends RESTDataSource {
constructor() {
super();
this.baseURL = "https://api.imgur.com/3/";
}
willSendRequest(request) {
request.headers.set("Content-Type","multipart/form-data");
request.headers.set(
"Authorization",`Client-ID ${process.env.IMGUR_CLIENT_ID}`
);
console.log(request);
}
async uploadImageFromUrl(url) {
const formData = new FormData();
formData.append("image",url);
return this.post("upload",formData);
}
}
我现在不再收到 We don't support that file type!
错误,但我仍然收到 400
响应,状态文本仅为 Bad Request
。上一代码片段中的 console.log()
打印:
{
method: 'POST',path: 'upload',body: FormData {
_overheadLength: 104,_valueLength: 80,_valuesToMeasure: [],writable: false,readable: true,dataSize: 0,maxDataSize: 2097152,pauseStreams: true,_released: false,_streams: [
'----------------------------594660553626244976225816\r\n' +
'Content-Disposition: form-data; name="image"\r\n' +
'\r\n','https://upload.wikimedia.org/wikipedia/commons/a/a0/Sunflower_as_gif_websafe.gif',[Function: bound ]
],_currentStream: null,_insideLoop: false,_pendingNext: false,_boundary: '--------------------------594660553626244976225816'
},params: URLSearchParams {},headers: Headers {
[Symbol(map)]: [Object: null prototype] {
'Content-Type': [Array],Authorization: [Array]
}
}
}
我在这里错过了什么? API 似乎正在接受我的表单数据,所以我认为其他标题之一可能存在一些问题,但在 Postman 中看起来只有几个必需的标题,其中大部分是计算出来的(例如 Content-Length
),所以我假设 apollo-datasource-rest
必须处理这个。
解决方法
对 multipart/form-data
进行了更多研究后,我发现 boundary
参数是必需的,必须将其添加到请求中的 Content-Type
值中才能使服务器能够解析有效载荷。此外,我无法将其手动设置为请求中的参数(至少不是以实际工作的方式)。 Postman 通常会在发送请求时计算此字段,但 apollo-datasource-rest
不会自动处理。
将 Content-Type
更改为 application/x-www-form-urlencoded
并使用 url 编码字符串代替 form-data
解决了该问题。
这是更新后的代码:
willSendRequest(request) {
request.headers.set("Content-Type",`application/x-www-form-urlencoded`);
request.headers.set(
"Authorization",`Client-ID ${process.env.IMGUR_CLIENT_ID}`
);
console.log(request);
}
async uploadImageFromUrl(url) {
const formData = `image=${url}&album=${process.env.IMGUR_ALBUM_DELETE_HASH}&type=url`;
return this.post("upload",formData);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。