Ajaxで画像アップロード。FormData使用

Laravel

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');

   ....後続の処理

のようにいつも通りの処理でデータを受け取れます!

参考サイト

formタグ使わないFormData送信

FromDataの使いかた

タイトルとURLをコピーしました