web-dev-qa-db-ja.com

ファイルをアップロードするときにフォームenctype = multipart / form-dataが必要なのはなぜですか?

なぜ<form enctype=multipart/form-data>ファイルをWebサーバーにアップロードするときに必要ですか?

44
Devi

ブラウザがHTTP経由で送信するためにバイナリおよびフォームデータをパッケージ化する方法に関係しています。デフォルトではフォームデータのみが送信されますが、フォームがファイルのアップロードをサポートする必要がある場合、バイナリデータも追加してフォームデータから分離する必要があります。

スコット・ハンセルマンはこれについて良い説明をします ここ

HTTPおよびHTTPを介したファイルアップロードの仕組み

私にとって、何が起こっているのかを理解することは常に良いことです。 「理由」または「何でも、それを追加するだけで機能します」と言う場合、それは悲しいと思います。何らかの理由で多くの人がFORM POSTを理解し、一般にフォームデータがサーバーに渡される方法を理解していますが、ファイルが転送されると、多くの人がそれが魔法であると結論付けます。ファイルのアップロードを含むフォームにenctype = "multipart/form = data"を追加する必要があるのはなぜですか?これは、フォームが複数の部分でPOSTされるためです。

このようなフォームがある場合:

<form action="/home/uploadfiles" method="post" enctype="multipart/form-data">
    <label for="file">Filename:</label>
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" value="Submit" />
</form>

結果のフォームPOSTは次のようになります(少し簡略化されています):

POST /home/uploadfiles HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------7d81b516112482 
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 324

-----------------------------7d81b516112482 
Content-Disposition: form-data; name="file"; filename="\\SERVER\Users\Scott\test.txt"
Content-Type: text/plain

foo
-----------------------------7d81b516112482
Content-Disposition: form-data; name="submit"

Submit
-----------------------------7d81b516112482--

このPOSTについていくつか注意してください。最初に、content-typeとboundary = ""に注意し、境界が後でどのように使用されるか、正確には、複数のパーツ間の境界に注意してください。最初の部分が、text/plainタイプの単一のファイルをアップロードしたことを示しています。これから、すべてが一度にPOSTされた場合に複数のファイルがどのように表示されるかを予測できます。

そしてもちろん、これが単なる基本形式である場合のこれの違いを見てくださいPOST enctype = "multipart/form = data"が含まれていない場合:

POST /home/uploadfiles HTTP/1.1 
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 13

submit=Submit

コンテンツタイプの違いをご覧ください。これは通常の典型的なフォームPOSTです。おそらく、送信ボタンのみが含まれているという点で非定型です! ....

余談ですが、複数の添付ファイルがあるメールを見ると、最初のHTTPメッセージの本文と非常によく似ています。マルチパートMIMEエンコードはどこにでもあるため、ほとんどの優れたアイデアに共通しています。

74
Nathan Taylor

これは RFC-1867 で説明されているHTMLファイルアップロードの仕様の一部です。これは、HTMLフォームでファイルのアップロードを許可する提案でした(1995年頃)。

セクション2から:

この提案は、HTMLに2つの変更を加えます。

1)INPUTのTYPE属性にFILEオプションを追加します。
2)INPUTタグのACCEPT属性を許可します。これは、入力に許可されるメディアタイプまたはタイプパターンのリストです。

さらに、新しいMIMEメディアタイプmultipart/form-dataを定義し、HTMLユーザーエージェントの解釈時の動作を指定します
ENCTYPE="multipart/form-data"および/または<INPUT type="file">を含むフォーム
タグ。

enctypemultipart/form-dataに設定すると、ブラウザはアップロードの各ファイルまたは添付ファイルを「マルチパート境界」で区切ります。これは、各「パート」の開始と終了を定義する一意の識別子です。

これにより、ブラウザは1つのリクエストで複数の部分(名前)を送信し、MIMEタイプ、ファイル名などの独自のメタデータで各部分を識別できます。

2
isapir