1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
---
title: FormData オブジェクトの使用
slug: Web/API/FormData/Using_FormData_Objects
tags:
- AJAX
- Blob
- File
- FormData
- Forms
- XHR
- XMLHttpRequest
translation_of: Web/API/FormData/Using_FormData_Objects
---
<div>{{APIRef("XMLHttpRequest")}}</div>
<p class="summary"><code><a href="/ja/docs/Web/API/FormData">FormData</a></code> オブジェクトは、<code><a href="/ja/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> を使用して送信するためのキーと値のペアのセットを収集可能にします。本来はフォームデータの送信に使用することを想定していましたが、キーのついたデータを伝送するためにフォームとは独立して使用することもできます。伝送されるデータは、フォームのエンコードタイプが <code>multipart/form-data</code> に設定されている場合に、{{domxref("HTMLFormElement.submit","submit()")}} メソッドで送信する際に使用するデータと同じ形式です。</p>
<h2 id="Creating_a_FormData_object_from_scratch">ゼロから FormData オブジェクトを作成する</h2>
<p>以下のように <code>FormData</code> オブジェクトはあなた自身で作成でき、インスタンス化したら {{domxref("FormData.append","append()")}} メソッドを呼び出すことでフィールドに付加します:</p>
<pre class="brush: js">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);
</pre>
<div class="note"><strong>注:</strong> フィールド "userfile" および "webmasterfile" はどちらも、ファイルを含んでいます。フィールド "accountnum" に与えた数値は <a href="/ja/docs/Web/API/FormData#append()"><code>FormData.append()</code></a> メソッドにより直ちに文字列へ変換されます (フィールドの値として {{ domxref("Blob") }}、 {{ domxref("File") }}、または文字列をとることができます。<strong>値が Blob でもファイルでもない場合は、文字列に変換されます</strong>)。</div>
<p>この例では、 "username", "accountnum", "userfile", "webmasterfile" というフィールドの値を含む <code>FormData</code> インスタンスを構築し、 <code>XMLHttpRequest</code> のメソッド <a href="/ja/docs/Web/API/XMLHttpRequest#send()"><code>send()</code></a> を使用してフォームのデータを送信します。 "webmasterfile" というフィールドは {{domxref("Blob")}} です。 <code>Blob</code> オブジェクトは、不変的な生データのファイルのようなオブジェクトを表します。 Blob は、必ずしも JavaScript に適した形式ではないデータを表します。 {{ domxref("File") }} インターフェースは <code>Blob</code> をベースにしており、 Blob の機能を継承し、ユーザーのシステム上のファイルをサポートするように拡張されています。 <code>Blob</code> を作成するには、 {{domxref("Blob.Blob","Blob() constructor")}} コンストラクターを呼び出します。</p>
<h2 id="Retrieving_a_FormData_object_from_an_HTML_form">HTML フォームから FormData オブジェクトを取り出す</h2>
<p>既存の {{ HTMLElement("form") }} のデータを含む <code>FormData</code> オブジェクトを構築するには、 <code>FormData</code> オブジェクトの作成時にその form 要素を指定します。</p>
<div class="note">
<p><strong>注</strong>: FormData は name 属性を使用する入力フィールドのみを使用します。</p>
</div>
<pre class="brush: js">var formData = new FormData(someFormElement);
</pre>
<p>例:</p>
<pre class="brush: js">var formElement = document.querySelector("form");
var request = new XMLHttpRequest();
request.open("POST", "submitform.php");
request.send(new FormData(formElement));
</pre>
<p>以下のように、<code>FormData</code> オブジェクトをフォームより取得してから送信するまでの間に、追加のデータを付加することもできます。</p>
<pre class="brush: js">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);</pre>
<p>これにより、必ずしもユーザーが編集可能である必要がない追加情報を含めるために、送信前にフォームデータを拡張することができます。</p>
<h2 id="Sending_files_using_a_FormData_object">FormData オブジェクトを使用したファイルの送信</h2>
<p><code>FormData</code> を使用してファイルを送信することもできます。type が "file" である {{HTMLElement("input")}} 要素を、{{htmlelement("form")}} に含めます。</p>
<pre class="brush: html"><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>
</pre>
<p>そして、以下のようなコードを使用して送信できます。</p>
<pre class="brush: js">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);
</pre>
<div class="note">
<p><strong>注</strong>: フォームへの参照を渡した場合は、 open() の呼び出しで指定した<a href="/ja/docs/Web/HTTP/Methods">リクエストメソッド</a>よりもフォームで指定したメソッドを優先します。</p>
</div>
<div class="warning">
<p><strong>警告</strong>: FormData を使用して、{{ domxref("XMLHttpRequest") }} または {{ domxref("Fetch_API") }} を使用して、 <code>multipart/form-data</code> の Content-Type で POST リクエストを送信する場合 (Files や Blob をサーバーにアップロードする場合など)、リクエストの <a href="/ja/docs/Web/HTTP/Headers/Content-Type"><code>Content-Type</code></a> ヘッダーを明示的に設定しないでください。そうすると、ブラウザーがリクエスト本文のフォームフィールドの区切りに使用する境界の表現で Content-Type ヘッダーを設定することができなくなります。</p>
</div>
<p>以下のように、直接 {{ domxref("File") }} や {{ domxref("Blob") }} を{{ domxref("FormData") }} オブジェクトへ追加することもできます。</p>
<pre class="brush: js">data.append("myfile", myBlob, "filename.txt");
</pre>
<p>{{domxref("FormData.append","append()")}} メソッドを使用する際は、オプションの第 3 引数を使用して、<code>Content-Disposition</code> ヘッダーに含めるファイル名を渡すことができます。これはサーバーへ送信されます。ファイル名を指定しない (あるいは引数がサポートされない) 場合は、 "blob" という名前が使用されます。</p>
<h2 id="Using_a_formdata_event">formdata イベントの使用</h2>
<p>{{domxref("FormData")}} オブジェクトよりも新しくプラットフォームに追加されたのが <a href="/ja/docs/Web/API/HTMLFormElement/formdata_event"><code>formdata</code> イベント</a>です。これは、フォームのデータを表すエントリーのリストが作成された後に {{domxref("HTMLFormElement")}} オブジェクトで発行されます。このイベントは、フォームが送信されたときに発行されますが、 {{domxref("FormData.FormData", "FormData()")}} コンストラクターが呼び出されたときにも発行されます。</p>
<p>これにより、 {{domxref("FormData")}} オブジェクトを <code>formdata</code> イベントの発行を受けてすばやく取得することができるようになり、自分でまとめる必要がなくなります。</p>
<p>一般的には、<a href="https://long-impatiens.glitch.me/">シンプルな formdata イベントのデモ</a>のように、 JavaScript でフォームを参照して使用します。</p>
<pre class="brush: js">const formElem = document.querySelector('form');</pre>
<p><a href="/ja/docs/Web/API/HTMLFormElement/submit_event"><code>submit</code> イベント</a>のハンドラーでは、 <code><a href="/ja/docs/Web/API/Event/preventDefault">preventDefault</a></code> を使用して既定のフォーム送信を停止してから、 {{domxref("FormData")}} コンストラクターを呼び出して <code>formdata</code> イベントを発行させます。</p>
<pre class="brush: js">formElem.addEventListener('submit', (e) => {
// on form submission, prevent default
e.preventDefault();
// construct a FormData object, which fires the formdata event
new FormData(formElem);
});</pre>
<p><code>formdata</code> イベントが発行されると、 {{domxref("FormDataEvent.formData")}} を使って {{domxref("FormData")}} オブジェクトにアクセスし、必要な処理を行うことができます (以下では、 {{domxref("XMLHttpRequest")}} を使ってサーバーに送信しています)。</p>
<pre class="brush: js">formElem.addEventListener('formdata', (e) => {
console.log('formdata fired');
// Get the form data from the event object
let data = e.formData;
for (var value of data.values()) {
console.log(value);
}
// submit the data via XHR
let request = new XMLHttpRequest();
request.open("POST", "/formHandler");
request.send(data);
});</pre>
<div class="notecard note">
<p><strong>注</strong>: <code>formdata</code> イベントと {{domxref("FormDataEvent")}} オブジェクトは、 Chrome ではバージョン 77 (および同等の Chromium) から、 Firefox ではバージョン 72 から利用可能です (Firefox 71で <code>dom.formdata.event.enabled</code> を設定することで初めて利用可能になりました)。</p>
</div>
<h2 id="Submitting_forms_and_uploading_files_via_AJAX_without_FormData_objects"><code>FormData</code> オブジェクトを<em>使用せずに</em> AJAX でフォームやファイルを送信する</h2>
<p>FormData オブジェクトを<em>使用せず</em>に、<a href="/ja/docs/Web/Guide/AJAX">AJAX</a> でシリアライズしたり送信したりする方法を知りたい場合は、 <a href="/ja/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#submitting_forms_and_uploading_files">こちらの節</a>を参照してください。</p>
<h2 id="See_also">関連情報</h2>
<ul>
<li><a href="/ja/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest">Using XMLHttpRequest</a></li>
<li>{{domxref("HTMLFormElement")}}</li>
<li>{{domxref("Blob")}}</li>
<li><a href="/ja/docs/Web/JavaScript/Typed_arrays">型付き配列</a></li>
</ul>
|