[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にしています。
これで簡単な画像アップロードができるようになりました。