input要素に画像を選択したら、裏側でストレージ保存してくれる機能を実装したく
Ajaxを使用しました。
フォーム形式でないデータをAjaxで扱ったことはあるものの、フォームデータは初めてでかなり詰まってしまいました。
今後のためにメモメモ。
HTML側
HTMLは普通のフォームタグとtype=fileのinputタグです。
今回は必要ないのでformタグにid属性をつけていません。
<form method="POST" accept=".png,.jpg,.jpeg,.gif">
<h3>画像アップロード</h3>
<input type="file" class="js-droparea" id="upload_file" name="upload_file">
</form>JS側
ちょっと長いですが、大事なのは前半の送信データ作成部分です。
$dropArea.on('change', function () { //画像情報が入って(changeしたら)きたら
var fd = new FormData(); //画像データ送信に必要なFromDataインスタンス作成
fd.append('image', $(this).prop('files')[0]); //取得した画像データを追加
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
},
url: 'create/store_image',
type: 'POST',
data: fd,
processData: false, // jQuery がデータを処理しないよう指定
contentType: false, // これがないと渡ったデータがおかしくなりphpで処理できない
dataType: 'text'
})
.done(function (result) {
if (result == 'success') {
alert('ok');
} else if (result == 'error') {
alert('error');
} else {
alert('その他です');
}
})
.fail(function (data) {
alert('通信に失敗しました');
})
});
.done以降はPHPから返ってきた値によって分岐しています。
通信が成功したら’success’, 失敗したら’error’がPHP側からかえるようにしています。
(なので dataType: ‘text’ としています)
詰まりポイント
data: の指定
JSからPHP側にリクエストは届くのに、どうしてもフォームデータが入ってきません。
結果的には、初め
data: {
'file': fd,
},としていたのを、
data: fd,
と書くことで解決しました!!
contentType:false
上で散々書き換えている間にコメントアウトしてしまっていた
contentType: false
こちらもフォームデータ送信に重要なものでした。
やっと送信できたフォームデータの中身が文字化けして何も取得できなかったのですが、
こちらのコメントアウトを外したらちゃんとデータを
$request->file('image')で取れるようになりました。
ddできない
Ajaxの時はdd()しても表示されない。。と思っていましたが、
ddした内容は開発ツールの Response や Previewタグで表示できるようです。
開発ツールを開いて NetWorkタブをクリック→Fetch/XHRタブをクリック

Payload タブではこちらからの送信データが表示されます。
(contentType: false, をコメントアウト時のみ)
Laravelコントローラーでの取得
無事にデータがコントローラーへ渡せたら、
public function storeImage(Request $request)
{
$img = $request->file('image');
....後続の処理
のようにいつも通りの処理でデータを受け取れます!

