JavaScript
S3

S3にAWS:SDKを使わずpresigned_urlで画像をアップロードする。しかもブラウザじゃないJSスクリプトで。

大抵はこういう処理はブラウザで画像をアップするものである。
そうでなくとも、AWS:SDKを使ってやるものである。
しかし、今回の案件ではS3などのキーは手元になく、APIを叩きpresigned_urlを取得し、画像をS3にアップロードをどうしてもしたかった。(画面を作りたくなかった)

最終的なコード

  fetch(/* presigned_urlを発行するAPIリクエスト */)
  .then((presigned_url) => {
      const data = fs.readFileSync(path);
      const base64data = new Buffer(data, 'base64');
      return fetch(presigned_url, {
          method: "PUT",
          body: base64data,
          headers: {
              "Content-Encoding": "base64",
              "Content-Type": "image/jpeg",
              "Content-Length": base64data.byteLength
          }
      })
  })

苦労したところ

最終的なコードにしてみると大したことがないのだが、画像の読み込み方とリクエストに突っ込み、S3に納得してもらえるヘッダーの形になるまで非常に苦労した。

fs.createReadStreamで実装しようとすると

「Transfer-Encoding: chunk」に対応してないと言われて怒られる。
S3が対応していないようだ。
new Bufferをそのままの形で送ろうとしても同じように駄目。

Content-Lengthをきちんと付け、Chunk形式じゃないよとすることでなんとかアップロードに成功しました。

とりあえず最低限上記のヘッダーつけたらいけた。