Apollo REST 数据源和 Imgur API - 使用表单数据不断收到 400 错误请求

Apollo REST Data Source and Imgur API - Keep getting 400 Bad Request using form data

我正在尝试实现 apollo-datasource-rest 以处理 URL 通过 Imgur 的 API 上传的图片(此处的文档: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! 错误,但我仍然收到状态文本 Bad Request400 响应。上一个代码片段中的 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 似乎正在接受我的表单数据,所以我认为另一个 headers 可能存在一些问题,但在 Postman 中似乎只需要几个 headers,其中大部分是计算出来的(例如 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);
  }