0

我正在尝试apollo-datasource-rest通过 Imgur 的 API 处理通过 URL 上传的图像(此处的文档:https ://apidocs.imgur.com/ )

我最初收到一个400读取错误We don't support that file type!,并确定这是由于apollo-datasource-rest自动设置Content-Typeapplication/json. 使用 npm 包修复该问题后form-data,我的代码如下所示:

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必须处理那个。

4

1 回答 1

0

在对 进行了更多研究后multipart/form-data,我发现该boundary参数是强制性的,并且必须添加到Content-Type请求中的值中,服务器才能解析有效负载。此外,我无法手动将其设置为请求中的参数(至少不是以实际工作的方式)。Postman 通常在发送请求时计算此字段,但apollo-datasource-rest不会自动处理该字段。

更改Content-Typetoapplication/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);
  }
于 2021-04-21T19:22:03.710 回答