“FormData” – Alphabetical Advent Calendar 2013
この記事は賞味期限切れです。(更新から1年が経過しています)
“F” は FormData の “F”。
FormData
FormData は XMLHttpRequest Level 2 で新たにサポートされるオブジェクトで、Ajaxでの値の送信をより簡単な物にしてくれます。
FormData – Web API リファレンス | MDN
XMLHttpRequest Level 2 は新たに FormData インタフェースのサポートを追加します。FormData オブジェクトは、XMLHttpRequest の send() メソッドを用いることで簡単に送信が可能な、フォームフィールドおよびそれらの値から表現されるキーと値のペアのセットを簡単に構築する手段を提供します。
使い方は至って簡単で、new で生成して append メソッドでキーと値を登録するだけです。 値をセットした FormData オブジェクトは、XMLHttpRequest オブジェクトの send メソッドにそのまま渡せます。
var data = new FormData();
data.append("name", "john");
data.append("email", "john@example.com");
var xhr = new XMLHttpRequest();
xhr.open("POST", "send.php");
xhr.send(data);
form エレメントを渡して初期化する事もできます。そこに append で値を追加する事もできます。
var form = document.getElementById("myform");
var data = new FormData(form);
data.append("age", 18);
FormData でファイルの送信をする
FormData の嬉しい所は、Ajaxによるファイルの送信が非常に簡潔に書ける点です。 File API をサポートしている環境ならば、append の値に File オブジェクトを渡すことが出来るので、 非常に直感的なコードになりますね。 (FormDataをサポートしていてFile APIをサポートしていない環境があるのかどうかは分かりませんが)
ドラッグドロップからの送信
先日書いたようなドラッグドロップを利用して、ページにドロップされたファイルを即時にAjaxでサーバーに送ってみるシンプルな例です。 このコードは FormData も File API もサポートしている環境を前提としています。
※簡易化の為、XHR以外の部分は jQuery を使って記述しています。
$(window).on("dragover drop", function(e){
e.preventDefault();
});
$(document).on("drop", function(e){
var files = e.originalEvent.dataTransfer.files;
var data = new FormData();
$.each(files, function(i, file){
data.append("userfile[]", file);
});
var xhr = new XMLHttpRequest();
xhr.open("POST", "send.php");
xhr.addEventListener("readystatechange", function(e){ ... }, false);
xhr.send(data);
});
input[type=file] からの送信
ドラッグドロップではなく、フォームエレメントで選択されたファイルを送信してみた例です。 input[type=file] は、 files という名前で FileList を属性に持っているのでそれを参照します。
$("#form-test").on("submit", function(e){
e.preventDefault();
var data = new FormData();
var files = $("input[name=userfile]")[0].files;
$.each(files, function(i, file){
data.append("userfile[]", file);
});
// あとは前項と共通
});
FormData が使えない場合のファイルアップロード
FormData が使えない環境でXHRを使用したファイルのアップロードを実装する為には、 Ajaxリクエストの内容を自前でゴリゴリ書いていく必要があります。
Javascript: Uploading a file… without a file – Stack Overflow
上記URLの回答のコードの抜粋です。
function beginQuoteFileUnquoteUpload(data)
{
// Define a boundary, I stole this from IE but you can use any string AFAIK
var boundary = "---------------------------7da24f2e50046";
var xhr = new XMLHttpRequest();
var body = '--' + boundary + '\r\n'
// Parameter name is "file" and local filename is "temp.txt"
+ 'Content-Disposition: form-data; name="file";'
+ 'filename="temp.txt"\r\n'
// Add the file's mime-type
+ 'Content-type: plain/text\r\n\r\n'
+ data + '\r\n'
+ boundary + '--';
xhr.open("POST", "http://www.mysite.com/myuploadhandler.php", true);
xhr.setRequestHeader(
"Content-type", "multipart/form-data; boundary="+boundary
);
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
alert("File uploaded!");
}
xhr.send(body);
}
application/x-www-form-urlencoded だともう少し短いコードになっていましたが(引用元参照)、 multipart/form-data を Ajax で送るのはかなり手間がかかる様ですね。 要するに FormData がその辺を全てやってくれているわけで、大変有難いです。
コメント