<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>XHR &#8211; Mach3.laBlog</title>
	<atom:link href="https://blog.mach3.jp/tag/xhr/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.mach3.jp</link>
	<description></description>
	<lastBuildDate>Thu, 05 Dec 2013 01:34:31 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>&#034;FormData&#034; &#8211; Alphabetical Advent Calendar 2013</title>
		<link>https://blog.mach3.jp/2013/12/05/jaac2013-f-formdata.html</link>
		
		<dc:creator><![CDATA[mach3]]></dc:creator>
		<pubDate>Thu, 05 Dec 2013 01:34:31 +0000</pubDate>
				<category><![CDATA[Laboratory]]></category>
		<category><![CDATA[Advent Calendar 2013]]></category>
		<category><![CDATA[FormData]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[XHR]]></category>
		<guid isPermaLink="false">http://blog.mach3.jp/?p=3657</guid>

					<description><![CDATA[&#8220;F&#8221; は FormData の &#8220;F&#8221;。 FormData FormData は XMLHttpRequest Level 2 で新たにサポートされるオブジェクトで、Aj [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>&#8220;F&#8221; は FormData の &#8220;F&#8221;。</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh3.googleusercontent.com/-Q4SkYRel228/UqR4gkQ0ALI/AAAAAAAACYg/0QFHNDSWBQU/s400/ac2013-f.png" alt="F"/></figure>



<p></p>



<span id="more-3657"></span>



<h2 class="wp-block-heading">FormData</h2>



<p><strong>FormData</strong> は XMLHttpRequest Level 2 で新たにサポートされるオブジェクトで、Ajaxでの値の送信をより簡単な物にしてくれます。</p>



<p><a href="https://developer.mozilla.org/ja/docs/Web/API/FormData">FormData &#8211; Web API リファレンス | MDN</a></p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>XMLHttpRequest Level 2 は新たに FormData インタフェースのサポートを追加します。FormData オブジェクトは、XMLHttpRequest の send() メソッドを用いることで簡単に送信が可能な、フォームフィールドおよびそれらの値から表現されるキーと値のペアのセットを簡単に構築する手段を提供します。</p>
</blockquote>



<p>使い方は至って簡単で、new で生成して <strong>append</strong> メソッドでキーと値を登録するだけです。 値をセットした FormData オブジェクトは、XMLHttpRequest オブジェクトの send メソッドにそのまま渡せます。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">var</span> data = <span class="hljs-keyword">new</span> FormData();
data.append(<span class="hljs-string">"name"</span>, <span class="hljs-string">"john"</span>);
data.append(<span class="hljs-string">"email"</span>, <span class="hljs-string">"john@example.com"</span>);

<span class="hljs-keyword">var</span> xhr = <span class="hljs-keyword">new</span> XMLHttpRequest();
xhr.open(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"send.php"</span>);
xhr.send(data);
</code></span></pre>


<p>form エレメントを渡して初期化する事もできます。そこに append で値を追加する事もできます。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">var</span> form = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"myform"</span>);
<span class="hljs-keyword">var</span> data = <span class="hljs-keyword">new</span> FormData(form);
data.append(<span class="hljs-string">"age"</span>, <span class="hljs-number">18</span>);
</code></span></pre>


<h2 class="wp-block-heading">FormData でファイルの送信をする</h2>



<p>FormData の嬉しい所は、Ajaxによるファイルの送信が非常に簡潔に書ける点です。 File API をサポートしている環境ならば、append の値に File オブジェクトを渡すことが出来るので、 非常に直感的なコードになりますね。 （FormDataをサポートしていてFile APIをサポートしていない環境があるのかどうかは分かりませんが）</p>



<h3 class="wp-block-heading">ドラッグドロップからの送信</h3>



<p><a href="/2013/12/03/drag-and-drop-alphabetical-advent-calender-2013.html">先日書いたような</a>ドラッグドロップを利用して、ページにドロップされたファイルを即時にAjaxでサーバーに送ってみるシンプルな例です。 このコードは FormData も File API もサポートしている環境を前提としています。</p>



<p>※簡易化の為、XHR以外の部分は jQuery を使って記述しています。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">$(<span class="hljs-built_in">window</span>).on(<span class="hljs-string">"dragover drop"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    e.preventDefault();
});

$(<span class="hljs-built_in">document</span>).on(<span class="hljs-string">"drop"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    <span class="hljs-keyword">var</span> files = e.originalEvent.dataTransfer.files;
    <span class="hljs-keyword">var</span> data = <span class="hljs-keyword">new</span> FormData();
    $.each(files, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">i, file</span>)</span>{
        data.append(<span class="hljs-string">"userfile&#91;]"</span>, file);
    });

    <span class="hljs-keyword">var</span> xhr = <span class="hljs-keyword">new</span> XMLHttpRequest();
    xhr.open(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"send.php"</span>);
    xhr.addEventListener(<span class="hljs-string">"readystatechange"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{ ... }, <span class="hljs-literal">false</span>);
    xhr.send(data);
});
</code></span></pre>


<h3 class="wp-block-heading">input[type=file] からの送信</h3>



<p>ドラッグドロップではなく、フォームエレメントで選択されたファイルを送信してみた例です。 input[type=file] は、 <strong>files</strong> という名前で FileList を属性に持っているのでそれを参照します。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">$(<span class="hljs-string">"#form-test"</span>).on(<span class="hljs-string">"submit"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    e.preventDefault();
    <span class="hljs-keyword">var</span> data = <span class="hljs-keyword">new</span> FormData();
    <span class="hljs-keyword">var</span> files = $(<span class="hljs-string">"input&#91;name=userfile]"</span>)&#91;<span class="hljs-number">0</span>].files;
    $.each(files, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">i, file</span>)</span>{
        data.append(<span class="hljs-string">"userfile&#91;]"</span>, file);
    });

    <span class="hljs-comment">// あとは前項と共通</span>
});
</code></span></pre>


<h2 class="wp-block-heading">FormData が使えない場合のファイルアップロード</h2>



<p>FormData が使えない環境でXHRを使用したファイルのアップロードを実装する為には、 Ajaxリクエストの内容を自前でゴリゴリ書いていく必要があります。</p>



<p><a href="http://stackoverflow.com/questions/2198470/javascript-uploading-a-file-without-a-file">Javascript: Uploading a file&#8230; without a file &#8211; Stack Overflow</a></p>



<p>上記URLの回答のコードの抜粋です。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">beginQuoteFileUnquoteUpload</span>(<span class="hljs-params">data</span>)
</span>{
    <span class="hljs-comment">// Define a boundary, I stole this from IE but you can use any string AFAIK</span>
    <span class="hljs-keyword">var</span> boundary = <span class="hljs-string">"---------------------------7da24f2e50046"</span>;
    <span class="hljs-keyword">var</span> xhr = <span class="hljs-keyword">new</span> XMLHttpRequest();
    <span class="hljs-keyword">var</span> body = <span class="hljs-string">'--'</span> + boundary + <span class="hljs-string">'\r\n'</span>
             <span class="hljs-comment">// Parameter name is "file" and local filename is "temp.txt"</span>
             + <span class="hljs-string">'Content-Disposition: form-data; name="file";'</span>
             + <span class="hljs-string">'filename="temp.txt"\r\n'</span>
             <span class="hljs-comment">// Add the file's mime-type</span>
             + <span class="hljs-string">'Content-type: plain/text\r\n\r\n'</span>
             + data + <span class="hljs-string">'\r\n'</span>
             + boundary + <span class="hljs-string">'--'</span>;

    xhr.open(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"http://www.mysite.com/myuploadhandler.php"</span>, <span class="hljs-literal">true</span>);
    xhr.setRequestHeader(
        <span class="hljs-string">"Content-type"</span>, <span class="hljs-string">"multipart/form-data; boundary="</span>+boundary
    );
    xhr.onreadystatechange = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-keyword">if</span> (xhr.readyState == <span class="hljs-number">4</span> &amp;&amp; xhr.status == <span class="hljs-number">200</span>)
            alert(<span class="hljs-string">"File uploaded!"</span>);
    }
    xhr.send(body);
}
</code></span></pre>


<p>application/x-www-form-urlencoded だともう少し短いコードになっていましたが（引用元参照）、 multipart/form-data を Ajax で送るのはかなり手間がかかる様ですね。 要するに FormData がその辺を全てやってくれているわけで、大変有難いです。</p>



<h2 class="wp-block-heading">参考資料</h2>



<ul class="wp-block-list">
<li><a href="https://developer.mozilla.org/ja/docs/Web/Guide/Using_FormData_Objects?redirectlocale=ja&amp;redirectslug=DOM%2FXMLHttpRequest%2FFormData%2FUsing_FormData_Objects">FormData オブジェクトの利用 &#8211; Web developer guide | MDN</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
