hello-world
webエンジニアのメモ。とりあえずやってみる。

[js]jQueryのajaxで画像(ファイル)アップロードをする

公開日時

以前作成した画像アップロードAPIを使うサンプルを作ろうと思い、jQueryを使ってajaxで画像アップロードをやってみました。

  • layout
# app/views/layouts/application.html.erb

!DOCTYPE html>
<html>
<head>
  <title>UploadApi</title>
  <%= stylesheet_link_tag    'application', media: 'all' %>
  <%= csrf_meta_tags %>
</head>
<body>
  <%= yield %>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <script src="/js/upload.js" type="text/javascript"></script>
</body>
</html>
  • 画像アップロードフォーム
# app/views/user/index.html.erb

<form class='update'>
  name: <input type="text" name="name" required /><br />
  image: <input type="file" name="profile" accept="image/jpeg,image/png" required /><br />
  <input type="submit" value="upload" />
</form>

<div id="profile">
  <p>アップロードした画像が表示されます</p>
</div>
  • アップロードjs
# public/js/upload.js

(function(win, doc) {

  "use strict";

  $('form').submit(function(e) {
    e.preventDefault();

    var fd = new FormData($(this)[0]);
    // 個別にパラメータ指定する場合は以下のようにする
    //var fd = new FormData();
    //fd.append('name', $(this).find(':text[name="name"]').val());
    //fd.append('profile', $(this).find(':file[name="profile"]')[0].files[0]);

    $.ajax('/api/user/update', {
      method: "POST",
      processData: false,
      contentType: false,
      data: fd,
      dataType: 'json',
      success: function(json) {
        var img = $('<img>').attr('src', json.profile_url);
        $('#profile').append(img);
        $('form').find(':submit').attr('disabled', true);
      },
      error: function(json) {
        alert('エラーが発生しました');
      }
    });
  });

})(this, document);

最初、ajaxのdata部分に

{ profile: $(this).find(':file[name="profile"]').val() }

という風に書いていたのですが、それだとファイル名になってしまいうまくアップロードできないことが判明。

ファイルを送る場合はFormDataオブジェクトにformの内容を格納して送信するのが良いそうです。

また、processDatafalseにしてクエリ文字列への変換を無効化し、contentTypeもFormDataオブジェクトが決めてくれるのでfalseにしています。

これで簡単な画像アップロードができるようになりました。

参考


Related #js

[js]iPhoneの「ホーム画面追加」を促すポップアップを表示する

先日公開した「 平成アイコン」に 「ホーム画面追加」を促すポップアップを表示してみました。

スマホで鳴らせる「除夜の鐘」サイトを作りました

今日は大晦日ですね。ということで 先日、チラッとご紹介した「煩悩API」を使ったサイトを作ってみました。

[js][bootstrap]bootstrap-sliderを使ってスライダーをつくる

TwitterBootstrapを使っていた際に、スライダーで音量調節ができるようにしようと思ったのですが公式ドキュメントを見ても見つからず、調べていたら bootstrap-sliderというライブラリを発見 サンプルにもありますが、

CoffeeScriptでカウントダウンタイマーを作ってみる

参考URLに記載されていたjsのカウントダウンタイマーをCoffeeScriptで書いてみました。