はじめに
Laravelとフロントエンド(例えばReactやNext.js)の間で画像ファイルを送信する際にバイナリデータの送信ではなく、マルチパートフォームデータで送信する際は、formData
で送らないといけないのですが、AxiosでAPIを叩いてFormDataを送信する際になぜかLaravel側でデータが空配列になってしまう現象です。
エラー内容
問題の典型的なシナリオは、フロントエンドからLaravelのAPIへフォームデータを送信しようとすると、Laravel側で$request->all()
や$request->input()
が空の配列を返す状態です。
試したこと(現状)
- Content-Typeヘッダーの確認
- リクエストヘッダは問題なく
multipart/form-data; boundary=....
となっている
- リクエストヘッダは問題なく
- Laravelのルーティングとコントローラーの確認。
- 問題なし
- ブラウザのデベロッパーツールを使用してリクエストのペイロードを確認。
- 問題なくデータは入っている
**.ts
const formData = new FormData();
// テキストフィールドを追加
// formData.append('_method', 'PATCH');
for (const [key, value] of Object.entries(inputData)) {
if (key !== 'profileImage') {
formData.append(key, value);
}
}
// ファイルデータを追加
if (inputData.profileImage && inputData.profileImage instanceof File) {
formData.append('profileImage', inputData.profileImage);
}
axios.patch('/user/setting/profile', formData),
**.php
Route::patch('/user/setting/profile', PatchUserSettingProfileController::class)->name('user.setting.profile.patch');
原因
問題の主な原因は、HTTPメソッドPATCHやPUTを使用している場合、PHPがFormDataを正しく解析できないことにありました。
解決策
解決策としては、以下の二つの方法があります:
-
①擬似的なPATCHメソッドの使用:
- フロントエンドでPOSTメソッドを使用し、FormDataに_methodキーを追加してPATCHを指定して擬似的にpatchでPHP側に解釈させる
- 例:
formData.append('_method', 'PATCH');
を追加- axiosはpostにすることを忘れずに
-
②HTTPメソッドのオーバーライド:
- Axiosリクエストのヘッダーに
'X-HTTP-Method-Override': 'PATCH'
を追加して、Laravelに対してHTTPメソッドをPATCHとして解釈させる- axiosはpostにすることを忘れずに
- Axiosリクエストのヘッダーに
**.ts
axios.post('/user/test', formData, {
headers: {
'X-HTTP-Method-Override': 'PATCH',
},
}),
結果
上記のいずれかの方法を採用することで、FormDataを使用した際にLaravel側でデータが空になる問題を解決でき、
フォームデータとファイルを正しく送信し、期待通りのサーバー応答を得ることができます。
参考