FormData オブジェクトの利用

by 4 contributors:

FormData オブジェクトは、XMLHttpRequest を使用して送信するためのキーと値のペアのセットを収集可能にします。本来はフォームデータの送信に使用することを想定していましたが、キーのついたデータを伝送するためにフォームとは独立して使用することもできます。伝送されるデータは、フォームのエンコードタイプが "multipart/form-data" に設定されている場合に、submit() メソッドで送信する際に使用するデータと同じ形式です。

スクラッチから FormData オブジェクトを作成する

以下のように FormData オブジェクトはあなた自身で作成でき、インスタンス化したら append() メソッドを呼び出すことでフィールドに付加します:

var oMyForm = new FormData();

oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); // 数値 123456 は直ちに文字列 "123456" へ変換されます

// HTML の file input でのユーザ選択...
oMyForm.append("userfile", fileInputElement.files[0]);

// ファイルのような JavaScript のオブジェクト...
var oFileBody = '<a id="a"><b id="b">hey!</b></a>'; // 新しいファイルのボディ...
var oBlob = new Blob([oFileBody], { type: "text/xml"});

oMyForm.append("webmasterfile", oBlob);

var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);
注記: フィールド "userfile" および "webmasterfile" はどちらも、ファイルを含んでいます。フィールド "accountnum" に与えた数値は FormData.append() メソッドにより直ちに文字列へ変換されます (フィールドの値として BlobFile、または文字列をとることができます: 値が Blob でもファイルでもない場合は、文字列に変換されます)。

このサンプルでは "username"、"accountnum"、"userfile"、"webmasterfile" という名前のフィールドの値を持つ FormData のインスタンスを作成しており、またフォームのデータを送信するために XMLHttpRequestsend() メソッドを使用しています。フィールド "webmasterfile" は Blob です。Blob オブジェクトはイミュータブルで生データによる、ファイルのようなオブジェクトです。Blob は必ずしも JavaScript ネイティブ形式のデータを表すとは限りません。File インターフェイスは Blob を基にしており、blob の機能性を継承しつつユーザのシステムにあるファイル向けのサポートを拡張しています。Blob を作成するために、Blob コンストラクタを呼び出すことができます。

HTML フォームから FormData オブジェクトを取り出す

既存の <form> 由来のデータを含んでいる FormData オブジェクトを構築するために、FormData オブジェクトを作成する際に form 要素を指定できます:

var newFormData = new FormData(someFormElement);

例:

var formElement = document.getElementById("myFormElement");
var oReq = new XMLHttpRequest();
oReq.open("POST", "submitform.php");
oReq.send(new FormData(formElement));

以下のように、FormData オブジェクトをフォームより取得してから送信するまでの間に、追加のデータを付加することもできます:

var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
formData.append("serialnumber", serialNumber++);
oReq.send(formData);

これにより、必ずしもフォームでユーザが編集可能である必要がない追加情報を含めるために、送信前にフォームデータを拡張することができます。

FormData オブジェクトを使用してファイルを送信する

FormData を使用してファイルを送信することもできます。単に type が "file" である <input> 要素を含めます:

<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 />
</form>
<div id="output"></div>
<a href="javascript:sendForm()">Stash the file!</a>

そして、以下のようなコードを使用して送信できます:

function sendForm() {

  var
    oOutput = document.getElementById("output"),
    oData = new FormData(document.forms.namedItem("fileinfo"));

  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 uploading your file.<br \/>";
    }
  };

  oReq.send(oData);

}

このサンプルでは、行儀よくはありませんがサーバで動作している Perl CGI に出力内容を送って、HTTP エラーを処理していることに注意してください。

以下のように、FormData オブジェクトへ直接 FileBlob を追加することもできます:

data.append("myfile", myBlob, "filename.txt");

append メソッドを使用する際は省略可能な第 3 引数を使用して、Content-Disposition ヘッダに含めるファイル名を渡すことができます。これはサーバへ送信されます。ファイル名を指定しない (あるいは引数がサポートされない) 場合は、"blob" という名前を使用します。

正しいオプションを設定することで、jQuery と共に FormData を使用することもできます:

var fd = new FormData(document.getElementById("fileinfo"));
fd.append("CustomField", "This is some extra data");
$.ajax({
  url: "stash.php",
  type: "POST",
  data: fd,
  processData: false,  // jQuery がデータを処理しないよう指定
  contentType: false   // jQuery が contentType を設定しないよう指定
});

FormData オブジェクトを使用せずに AJAX でフォームやファイルを送信する

FormData オブジェクトを使用せずに、AJAX でシリアライズや送信する方法を知りたい場合は、こちらの節をご覧ください。

関連情報

ドキュメントのタグと貢献者

Contributors to this page: jgs, taiyaki32, ethertank, yyss
最終更新者: jgs,