12
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google Cloud Platform その2Advent Calendar 2018

Day 6

Google Cloud Storageの署名付きURLに対してaxiosでPUTするときにFormDataを使おうとしてはならない

Last updated at Posted at 2018-12-05

Google Cloud Platform その2 Advent Calendar 2018の6日目の投稿です。

axiosでファイルアップロードしようとして調べると、FormDataを利用する手順が世の中には数多くあります。

axios/axios: Promise based HTTP client for the browser and node.js
https://github.com/axios/axios

ただ、Google Cloud Storage(GCS)の署名付きURLに対してPUTする場合、FormDataは利用できないので、お気をつけください。

利用できない理由

FormDataは複数項目をまとめてアップロードできる仕組みで、Contnent-Typemultipart/form-data が自動で指定されます。ここまでなら、署名付きURL生成時にContnent-Typemultipart/form-data を指定すれば良いだけなのですが、multipart/form-data の場合、複数項目をアップロードする前提なので、区切り文字Boundary が含まれます。

こいつがリクエスト時にランダムで生成されるため、署名付きURLでContnent-Type に指定するにも指定できず詰みます。(詰みました~

だめな感じの実装(イメージ)

検証につかれて実行可能なコードを用意するのが疲れました
let uploadUrl = '';
await axios.get(`${apiRootUrl}signed_url?filename=${filename}&content_type=${contentType}`)
.then((res) => {
  uploadUrl = res.data.signed_url;
})
.catch((error) => {
  throw error;
});

const options = {
  headers: {
    'Content-Type': file.type, // ここで指定しても適用されないTT
  },
};

let data = new FormData();
data.append('file', file);
await axios.put(uploadUrl, data, options)
.then((res) => {
  console.log('成功!');
})
.catch((error) => {
  throw error;
});

いい感じの実装(イメージ)

散々ハマった挙げ句、動いた実装から一部持ってきました
let uploadUrl = '';
await axios.get(`${apiRootUrl}signed_url?filename=${filename}&content_type=${contentType}`)
.then((res) => {
  uploadUrl = res.data.signed_url;
})
.catch((error) => {
  throw error;
});

const options = {
  headers: {
    'Content-Type': file.type,
  },
};

await axios.put(uploadUrl, file, options)
.then((res) => {
  console.log('成功!');
})
.catch((error) => {
  throw error;
});

参考

axios/axios: Promise based HTTP client for the browser and node.js
https://github.com/axios/axios

multipart/form-dataのリクエストで地味にハマったメモ - Qiita
https://qiita.com/Zaki_Tk/items/073f597d52f6fd8e3dcd

FormData オブジェクトの利用 - ウェブデベロッパーガイド | MDN
https://developer.mozilla.org/ja/docs/Web/Guide/Using_FormData_Objects

12
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?