Edited at

axiosでPOSTした画像をLaravel APIで保存する

タイトルの通りです。画像やファイルのstorage保存の記事はいくつか見かけましたが、jsからPOSTする記事についてはあんまり見かけなかったので書きました。

この記事ではaxios経由で画像をPOST、LaravelのAPI処理に渡しているサンプルコードを簡単に説明します。概要は以下の通りです。


  1. canvasに画像を描画し、blobデータを作成

  2. blobをformDataにappendして、axiosでPOST

  3. POSTされたblobファイルを、Laravel API側で処理・保存


View側の処理


データのBLOB化

以下の処理かtoBlobを使ってCanvasに描画した画像ファイルをblob化します。


index.vue

// Canvasのデータをblob化

const type = 'image/png';
const dataurl = this.canvas.toDataURL(type); // this.canvasは用途に合わせて書き換え
const bin = atob(dataurl.split(',')[1]);
const buffer = new Uint8Array(bin.length);
for (let i = 0; i < bin.length; i++) {
buffer[i] = bin.charCodeAt(i);
}
const blob = new Blob([buffer.buffer], {type: type});

"multipart/form-dataのデータをPOSTするので、blobファイルをFormDataインタフェースにappendする形でデータを作成します。


index.vue

const data = new FormData();

data.append('photo', blob, 'image.png'); //'photo'というkeyで保存

blobを格納したdataをaxios.postの第二引数にセットすれば、POST可能です。


index.vue


axios.post('/api/photo', data, {
headers: { 'content-type': 'multipart/form-data' }
})
.then(res => {
console.log('success')
}).catch(error => {
new Error(error)
});


Laravel API側の処理

api用のControllerで設定したstore定義内に、受け取ったblobデータをファイルとして保存するための処理を書きます。View側でFormData内にappendしたphotoデータを$requestから参照し、storeAsメソッドを実行することで簡単に保存が可能です。


IndexController.php

  public function store(Request $request)

{
// ファイル名を取得
$filename = $request->photo->name;

// blobデータをstorageに保存する
// diskの指定を特にしなければ、例の場合。`storage/app/images/`に画像が保存される
$path = $request->photo->storeAs('images', $filename);
}