☁️

CloudflareのUpload via URLでBad request: incomplete multipart stream出た時

2024/05/03に公開

概要

以下のエンドポイントを使用して、画像をアップロードするときに
https://developers.cloudflare.com/api/operations/cloudflare-images-upload-an-image-via-url

{
  "result": null,
  "success": false,
  "errors": [
    {
      "code": 5400,
      "message": "Bad request: incomplete multipart stream"
    }
  ],
  "messages": []
}

という感じで失敗した。

APIリファレンスのサンプルは以下の通り(2024/05/03時点)

const form = new FormData();
form.append("file", "");
form.append("metadata", "");
form.append("requireSignedURLs", "");
form.append("url", "");

const options = {
  method: 'POST',
  headers: {
    'Content-Type': 'multipart/form-data; boundary=---011000010111000001101001',
    Authorization: 'Bearer undefined'
  }
};

options.body = form;

fetch('https://api.cloudflare.com/client/v4/accounts/account_id/images/v1', options)
  .then(response => response.json())
  .then(response => console.log(response))
  .catch(err => console.error(err));

失敗したときのコード

import { APP_CONTEXT } from '../../types'

const uploadImageFromUrlService = async (c: APP_CONTEXT, url: string, metadata: any) => {
  const apiEndpoint = `https://api.cloudflare.com/client/v4/accounts/${c.get('CLOUDFLARE_ACCOUNT_ID')}/images/v1`
  const form = new FormData()
  form.append('metadata', JSON.stringify(metadata))
  form.append('url', url)

  const response = await fetch(apiEndpoint, {
    method: 'POST',
    headers: {
      'Content-Type': 'multipart/form-data; boundary=---011000010111000001101001',
      Authorization: `Bearer ${c.get('CLOUDFLARE_API_KEY')}`,
    },
    body: form,
  })

  return await response.json()
}

export { uploadImageFromUrlService }

失敗してた理由

 // こいつ書かなくていいらしい
'Content-Type': 'multipart/form-data; boundary=---011000010111000001101001',

動いたコード

import { APP_CONTEXT } from '../../types'

const uploadImageFromUrlService = async (c: APP_CONTEXT, url: string, metadata: any) => {
  const apiEndpoint = `https://api.cloudflare.com/client/v4/accounts/${c.get('CLOUDFLARE_ACCOUNT_ID')}/images/v1`
  const form = new FormData()
  form.append('metadata', JSON.stringify(metadata))
  form.append('url', url)

  const response = await fetch(apiEndpoint, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${c.get('CLOUDFLARE_API_KEY')}`,
    },
    body: form,
  })

  return await response.json()
}

export { uploadImageFromUrlService }

でめたしでめたし

shinaps テックブログ

Discussion