FormData オブジェクトの利用
FormData
オブジェクトは、XMLHttpRequest
を使用して送信するためのキーと値のペアのセットを収集可能にします。本来はフォームデータの送信に使用することを想定していましたが、キーのついたデータを伝送するためにフォームとは独立して使用することもできます。伝送されるデータは、フォームのエンコードタイプが multipart/form-data
に設定されている場合に、submit()
メソッドで送信する際に使用するデータと同じ形式です。
スクラッチから FormData オブジェクトを作成する
以下のように FormData
オブジェクトはあなた自身で作成でき、インスタンス化したら append()
メソッドを呼び出すことでフィールドに付加します:
var formData = new FormData();
formData.append("username", "Groucho");
formData.append("accountnum", 123456); // 数値 123456 は直ちに文字列 "123456" へ変換されます
// HTML の file input でユーザが選択したファイル
formData.append("userfile", fileInputElement.files[0]);
// ファイルのような JavaScript オブジェクト
var content = '<a id="a"><b id="b">hey!</b></a>'; // 新しいファイルのボディ...
var blob = new Blob([content], { type: "text/xml"});
formData.append("webmasterfile", blob);
var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);
FormData.append()
メソッドにより直ちに文字列へ変換されます (フィールドの値として Blob
、File
、または文字列をとることができます: 値が Blob でもファイルでもない場合は、文字列に変換されます)。このサンプルでは "username"、"accountnum"、"userfile"、"webmasterfile" という名前のフィールドの値を持つ FormData
のインスタンスを作成しており、またフォームのデータを送信するために XMLHttpRequest
の send()
メソッドを使用しています。フィールド "webmasterfile" は Blob
です。Blob
オブジェクトはファイルに似たオブジェクトで、イミュータブルな生デーです。Blob は必ずしも JavaScript ネイティブ形式のデータを表すとは限りません。File
インターフェイスは Blob
を基にしており、blob の機能性を継承しつつユーザのシステムにあるファイル向けのサポートを拡張しています。Blob
を作成するために、Blob()
コンストラクタを呼び出すことができます。
HTML フォームから FormData オブジェクトを取り出す
既存の <form>
のデータを含む FormData
オブジェクトを構築するために、FormData
オブジェクトを作成する際にその form 要素を指定します:
var formData = new FormData(someFormElement);
例:
var formElement = document.querySelector("form");
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
request.send(new FormData(formElement));
以下のように、FormData
オブジェクトをフォームより取得してから送信するまでの間に、追加のデータを付加することもできます:
var formElement = document.querySelector("form");
var formData = new FormData(formElement);
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
formData.append("serialnumber", serialNumber++);
request.send(formData);
これにより、必ずしもユーザが編集可能である必要がない追加情報を含めるために、送信前にフォームデータを拡張することができます。
FormData オブジェクトを使用してファイルを送信する
FormData
を使用してファイルを送信することもできます。type が "file" である <input>
要素を、<form>
に含めます:
<form enctype="multipart/form-data" method="post" name="fileinfo">
<label>Your email address:</label>
<input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
<label>Custom file label:</label>
<input type="text" name="filelabel" size="12" maxlength="32" /><br />
<label>File to stash:</label>
<input type="file" name="file" required />
<input type="submit" value="Stash the file!" />
</form>
<div></div>
そして、以下のようなコードを使用して送信できます:
var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function(ev) {
var oOutput = document.querySelector("div"),
oData = new FormData(form);
oData.append("CustomField", "This is some extra data");
var oReq = new XMLHttpRequest();
oReq.open("POST", "stash.php", true);
oReq.onload = function(oEvent) {
if (oReq.status == 200) {
oOutput.innerHTML = "Uploaded!";
} else {
oOutput.innerHTML = "Error " + oReq.status + " occurred when trying to upload your file.<br \/>";
}
};
oReq.send(oData);
ev.preventDefault();
}, false);
注記: フォームへの参照を渡した場合は、open() の呼び出しで指定したメソッドよりもフォームで指定したメソッドを優先します。
以下のように、FormData
オブジェクトへ直接 File
や Blob
を追加することもできます:
data.append("myfile", myBlob, "filename.txt");
append()
メソッドを使用する際は省略可能な第 3 引数を使用して、Content-Disposition
ヘッダに含めるファイル名を渡すことができます。これはサーバへ送信されます。ファイル名を指定しない (あるいは引数がサポートされない) 場合は、"blob" という名前を使用します。
正しいオプションを設定することで、jQuery と共に FormData
を使用することもできます:
var fd = new FormData(document.querySelector("form"));
fd.append("CustomField", "This is some extra data");
$.ajax({
url: "stash.php",
type: "POST",
data: fd,
processData: false, // jQuery がデータを処理しないよう指定
contentType: false // jQuery が contentType を設定しないよう指定
});