enctype = 'multipart / form-data'はどういう意味ですか?


回答:


1570

POSTリクエストを行う場合、リクエストの本文を形成するデータを何らかの方法でエンコードする必要があります。

HTMLフォームは3つのエンコーディング方法を提供します。

  • application/x-www-form-urlencoded (デフォルト)
  • multipart/form-data
  • text/plain

の追加作業が行われてapplication/jsonいましたが、中止されました。

(HTMLフォームの送信以外の手段を使用して生成されたHTTPリクエストで他のエンコーディングが可能です。JSONはWebサービスで使用される一般的な形式であり、一部はまだSOAPを使用しています。)

形式の詳細は、ほとんどの開発者にとって重要ではありません。重要な点は次のとおりです。

  • 決して使用しないでくださいtext/plain

クライアント側のコードを書いているとき:

  • multipart/form-dataフォームに<input type="file">要素が含まれている場合に使用します
  • そうでなければ、使用することができるmultipart/form-dataapplication/x-www-form-urlencodedが、application/x-www-form-urlencodedより効率的になります

サーバーサイドコードを書いているとき:

  • 事前に記述されたフォーム処理ライブラリを使用する

ほとんど(Perl CGI->paramやPHPの$_POSTスーパーグローバルで公開されているものなど)が違いを処理します。サーバーが受け取った生の入力を解析しようとしないでください。

場合によっては、両方の形式を処理できないライブラリを見つけることがあります。Node.jsのフォームデータを処理するための最も一般的なライブラリは、マルチパートリクエストを処理できないbody-parserです(ただし、可能な代替策を推奨するドキュメントがあります)。


生データを解析または生成するためのライブラリを作成(またはデバッグ)している場合は、フォーマットについて考える必要があります。また、興味のためにそれについて知りたいかもしれません。

application/x-www-form-urlencoded URLの最後のクエリ文字列とほぼ同じです。

multipart/form-dataかなり複雑ですが、ファイル全体をデータに含めることができます。結果の例は、HTML 4仕様にあります。

text/plainはHTML 5によって導入され、デバッグのみに役立ちます。仕様から:コンピューターでは確実に解釈できないため、他のツール(ほとんどのブラウザーの開発者ツールのネットワークパネルなど)と組み合わせる方が良いと私は主張しますそのため)。


5
@Quentinすみません、すべてのフォームにマルチパートを使用すると、どのような問題が発生する可能性がありますか?とファイルを白くします。
Webinan 2013年

12
GETフォームでは意味がなく、リクエストのファイルサイズが大きくなります。
Quentin

@Quentinマルチパートフォームデータはデフォルトでストリームとして送信されますか?
グロウラー2017

enctypeのencは何かを表していますか?
フィリップ・レゴ2017

1
「HTMLフォームはENC odingの3つの方法を提供します」
Quentin

449

いつそれを使うべきか

クエンティンの答えは正しいです。multipart/form-dataフォームにファイルのアップロードが含まれている場合は使用し、application/x-www-form-urlencodedそれ以外の場合は省略しenctypeます。

私はするつもりだ:

  • さらにHTML5参照を追加する
  • 彼がフォーム送信の例で正しい理由を説明する

HTML5リファレンス

ある三つの可能性のためにはenctype

サンプルを生成する方法

各メソッドの例を見ると、それらがどのように機能するか、そしていつそれぞれを使用すべきかが明らかになります。

以下を使用して例を作成できます。

フォームを最小限の.htmlファイルに保存します。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <title>upload</title>
</head>
<body>
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
  <p><input type="text" name="text1" value="text default">
  <p><input type="text" name="text2" value="a&#x03C9;b">
  <p><input type="file" name="file1">
  <p><input type="file" name="file2">
  <p><input type="file" name="file3">
  <p><button type="submit">Submit</button>
</form>
</body>
</html>

デフォルトのテキスト値をに設定しますa&#x03C9;b。つまりaωbωはUTF-8のU+03C9バイト61 CF 89 62であるためです。

アップロードするファイルを作成します。

echo 'Content of a.txt.' > a.txt

echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html

# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary

小さなエコーサーバーを実行します。

while true; do printf '' | nc -l 8000 localhost; done

ブラウザでHTMLを開き、ファイルを選択して、送信をクリックし、ターミナルを確認します。

nc 受け取ったリクエストを出力します。

テスト済み:Ubuntu 14.04.3、ncBSD 1.105 、Firefox 40。

multipart / form-data

Firefoxが送信しました:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"

text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"

aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

Content of a.txt.

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html

<!DOCTYPE html><title>Content of a.html.</title>

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream

aωb
-----------------------------735323031399963166993862150--

バイナリファイルとテキストフィールドの場合、バイト61 CF 89 62aωbUTF-8)は文字通り送信されます。あなたはそれをnc -l localhost 8000 | hdバイトで確認することができます:

61 CF 89 62

送信されました(61== 'a'および62== 'b')。

したがって、次のことが明らかです。

  • Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150コンテンツタイプをに設定multipart/form-dataし、フィールドが指定されたboundary文字列で区切られていることを伝えます。

    ただし、次のことに注意してください。

    boundary=---------------------------735323031399963166993862150

    --実際の障壁より2つ少ないダッシュがあります

    -----------------------------735323031399963166993862150

    これは、標準では境界が2つのダッシュで始まる必要があるため--です。他のダッシュは、Firefoxが任意の境界を実装するために選択した方法のようです。RFC 7578は、これらの2つの先行ダッシュ--が必要であることを明確に述べています。

    4.1。multipart / form-dataの「境界」パラメーター

    他のマルチパートタイプと同様に、パーツは、CRLF、「-」、および「boundary」パラメーターの値を使用して構築された境界区切り文字で区切られます。

  • すべてのフィールドは、そのデータの前にいくつかのサブヘッダを取得しますContent-Disposition: form-data;、フィールドはnamefilenameデータが続きます。

    サーバーは次の境界文字列までデータを読み取ります。ブラウザはどのフィールドにも表示されない境界を選択する必要があるため、リクエスト間で境界が異なる場合があります。

    一意の境界があるため、データのエンコードは必要ありません。バイナリデータはそのまま送信されます。

    TODO:最適な境界サイズは何log(N)ですか(私はきっと)、それを見つけるアルゴリズムの名前/実行時間は?質問:https : //cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences

  • Content-Type ブラウザによって自動的に決定されます。

    正確にどのように決定されるのかが尋ねられました:アップロードされたファイルのMIMEタイプはブラウザによってどのように決定されますか?

application / x-www-form-urlencoded

今変更enctypeapplication/x-www-form-urlencoded、ブラウザ、および再送信をリロードします。

Firefoxが送信しました:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51

text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary

明らかにファイルデータは送信されず、ベース名のみが送信されました。したがって、これはファイルには使用できません。

テキストフィールドのように、我々は次のようにその通常の印刷可能な文字を見るaと、b非印刷可能なもののような一方で、1バイトで送信された0xCF0x89取り上げた3バイトごと:%CF%89

比較

多くの場合、ファイルのアップロードには印刷できない文字(画像など)がたくさん含まれていますが、テキストフォームにはほとんど含まれていません。

例から、次のことがわかりました。

  • multipart/form-data:数バイトの境界オーバーヘッドをメッセージに追加し、メッセージの計算にある程度の時間を費やす必要がありますが、各バイトを1バイトで送信します。

  • application/x-www-form-urlencoded:フィールドごとに1バイト境界(&)がありますが、印刷できない文字ごとに3倍の線形オーバーヘッド係数が追加されます。

したがって、でファイルを送信できたとしても、application/x-www-form-urlencoded効率が悪いため、送信したくありません。

ただし、テキストフィールドにある印刷可能な文字の場合、問題はなく、オーバーヘッドも少ないので、そのまま使用します。


3
@ Khanna111 %CFは3バイト長です:%CおよびF:-)人間が読めるようにするストーリー。
Ciro Santilli冠状病毒审查六四事件法轮功

6
OS Xには、nc両方受け入れない-l-p同時に引数を。しかし、これは私にとってはうまくいきます:while true; do printf '' | nc -l 8000; done
PhilipS 2017

4
言及されてContent-Typeいない小さいが重要な点は、で指定された境界のハイフン(--)が2つ少ないことです。つまり、実際にメッセージ本文で境界を使用する場合は、接頭辞としてを付ける必要があります--。また、最後の境界には接尾辞としてを付ける必要がありますが--、これは簡単にわかります。stackoverflow.com/questions/3508252/…を
Bernard

1
私の知る限り、境界にANY DASHES AT ALLを置くことのポイントは、リクエストの構文を目で確認することを不可能にすることです。境界トークンでは使用しないでください。
Dewi Morgan

1
@DewiMorganあなたは完全に正しいです。投稿を編集して、境界文字列からダッシュを削除しました。
最大

91

enctype='multipart/form-dataPOSTを介してファイルを送信できるようにするエンコードタイプです。簡単に言うと、このエンコードがなければ、ファイルをPOST経由で送信することはできません。

ユーザーがフォームを介してファイルをアップロードできるようにする場合は、このenctypeを使用する必要があります。


したがって、ファイルがバイナリファイルでない場合、これなしで作業できますか?
Yugal Jindle 2013

私が理解していることから、multipart/form-data非バイナリファイルの送信に使用できますが、非効率的です。application/x-www-form-urlencoded非バイナリデータを送信するには、使用するのが正しい方法だと思いますが、非バイナリファイルの経験が豊富な方は、私を修正する必要があるかもしれません。
マットアズベリー2013

11
multipart/form-dataファイルの送信に使用する主な利点は、ファイルがフロントエンドとバックエンドの両方で自動的に機能することです。特別な処理を行う必要はありません。テキストのみを含む必要がある場合でも、すべてのファイルはバイナリです。 application/x-www-form-urlencoded添付ファイルなしでフォームをPOSTする標準的な方法です。multipart/form-data添付ファイルのあるフォームをPOSTする標準的な方法です。(また、サーバーやクライアント間の通信に一般的なapplication/jsonやなど、他にも多数のエンコーディングapplication/json-patch+jsonがあります。)
Daniel Luna

6
画像をbase64エンコードしてプレーンな文字列データとして送信できることを指摘しておく価値はあります。
ジェームズ

3
上記の@Prosperoのコメントに加えて、を使用せずにPOST経由でファイルを完全に送信できますmultipart/form-data。あなたがすることはできませんやっていることはJavaScriptをせずに、通常のHTMLフォーム送信を使用してそれを行うです。フォームを使用するように設定することmultipart/form-dataは、JavaScriptを使用せずにファイルをPOSTするためにHTMLが提供する唯一のメカニズムです。これは答えが十分に明確ではないように感じます。そして、世間知らずな読者multipart/form-dataは、ファイルを送信できないとHTTPの制限であると考えるかもしれません。そうではありません。
Mark Amery

81

フォームを送信するときは、HTTPプロトコルを介して、TCP / IPプロトコルメッセージ構造に適切にエンベロープされたネットワーク上のメッセージを送信するようにブラウザに指示します。HTMLページには、<form>s を使用してサーバーにデータを送信する方法があります。

フォームが送信されると、HTTPリクエストが作成されてサーバーに送信されます。メッセージには、フォーム内のフィールド名とユーザーが入力した値が含まれます。この送信は、POSTまたはGET HTTPメソッドで発生する可能性があります

  • POST ブラウザにHTTPメッセージを作成し、すべてのコンテンツをメッセージの本文に含めるように指示します(非常に便利な方法で、より安全で柔軟性があります)。
  • GETクエリ文字列でフォームデータを送信します。データ表現と長さに関していくつかの制約があります。

フォームをサーバーに送信する方法の説明

属性enctypeは、POSTメソッドを使用する場合にのみ意味があります。指定すると、コンテンツを特定の方法でエンコードしてフォームを送信するようにブラウザに指示します。MDNから-フォームenctype

method属性の値がpostの場合、enctypeは、フォームをサーバーに送信するために使用されるコンテンツのMIMEタイプです。

  • application/x-www-form-urlencoded:これがデフォルトです。フォームが送信されると、すべての名前と値が収集され、最終的な文字列に対してURLエンコーディングが実行されます。
  • multipart/form-data:文字はエンコードされません。これは、フォームにファイルアップロードコントロールがある場合に重要です。ファイルバイナリを送信すると、ビットストリームが変更されないことが保証されます。
  • text/plain:スペースは変換されますが、エンコードは実行されません。

安全保障

フォームを送信すると、RFC 7578セクション7:マルチパートフォームデータ-セキュリティに関する考慮事項に記載されているように、いくつかのセキュリティ上の懸念が発生する可能性があります

すべてのフォーム処理ソフトウェアは
、機密
情報または個人を特定する情報を含むことが多いため、ユーザー提供のフォームデータを機密性をもって処理する必要があります。Webブラウザーではフォームの「自動入力」機能が広く使用されています。これらは、
他の
無害なタスクを完了するときに、ユーザーを知らずに機密情報を送信するように仕向けるために使用される可能性があります。multipart / form-dataは
、整合性のチェック、機密性の保証、ユーザーの
混乱の回避、またはその他のセキュリティ機能を提供しません。これらの懸念は
、フォーム入力およびフォームデータ解釈アプリケーションで対処する必要があります。

フォームを受信して​​フォームを処理するアプリケーションは、送信を意図していない要求元のフォーム処理サイトにデータを返さないように注意する必要があります。

Content-
Dispositionヘッダーフィールドのファイル名を解釈するときに、
受信者のファイルスペース内のファイルを誤って上書きしないことが重要です。

これは、あなたが開発者であり、サーバーがユーザーによって送信されたフォームを処理する場合に関係し、最終的に機密情報が含まれる可能性があります。


1
最新の編集後のセキュリティに関することはすべて、何をするかという問題とは無関係enctypeです。私はそれが文字通りから知っているmultipart/form-dataRFCが、それでもそれは、データは次のように送られているかどうかに完全に直交しているフォーム提出に関するセキュリティ上の考慮事項の任意のダンプだapplication/x-www-form-urlencodedかをmultipart/form-data
Mark Amery

38

enctype='multipart/form-data'文字はエンコードされません。そのため、サーバーにファイルをアップロードするときにこのタイプが使用されます。
したがってmultipart/form-data、フォームがファイルのコンテンツなどのバイナリデータのアップロードを必要とする場合に使用されます。


8

フォームを使用してファイルのコンテンツをURLパラメータ内に配置することはできないため、method属性をPOSTに設定します。

データは複数の部分に分割されるため、enctypeの値をmultipart / form-dataに設定します。各ファイルに1つと、一緒に送信されるフォーム本文のテキストに1つです。


これPOSTは、フォームを介してファイルを送信するのに十分である可能性が高く、追加multipart/form-dataは漠然とした方法でのボーナスにすぎないことを意味します。そうではありません。ほとんどのファイルでは、絶対にを使用する必要がありますmultipart/form-data
underscore_d 2017年

1
  • enctype(ENC ode TYPE)属性は、フォームデータをサーバーに送信するときにエンコードする方法を指定します。
  • multipart / form-data はenctype属性の値の1つであり、ファイルアップロードを持つフォーム要素で使用されます。マルチパートとは、フォームデータが複数のパートに分割され、サーバーに送信されることを意味します。

5
enctypeは暗号化タイプを意味しないと思います。このレベルでは暗号化は行われません。私の推測では、エンコードタイプまたは囲まれたタイプのいずれかです。しかし、それは確かに暗号化タイプではありません。
Yeo

1
ここについての最終的な箇条書き<head><body>は無関係と混乱です。
Mark Amery

0

通常、これは、ファイルのアップロードをデータとして取得する必要があるPOSTフォームがある場合です。これにより、転送されたデータをエンコードする方法がサーバーに通知されます。このような場合は、転送してアップロードするだけなのでエンコードされません。サーバーへのファイル、たとえば画像やPDFのアップロード時など


-3

enctype属性は、フォームデータをサーバーに送信するときにエンコードする方法を指定します。

enctype属性は、method = "post"の場合にのみ使用できます。

文字はエンコードされません。この値は、ファイルアップロードコントロールがあるフォームを使用している場合に必要です。

W3Schoolsから


2
この引用は言及さえしていませんmultipart/form-data。それもかなり不明確です。「文字がエンコードされていません」という文はどういう意味ですか?-1。
Mark Amery
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.