1693

enctype='multipart/form-data'HTML フォームの意味と、それをいつ使用する必要があるか?

4

10 に答える 10

1861

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-dataorを使用できますapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded、より効率的になります

サーバー側のコードを書いている場合:

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

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

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


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

application/x-www-form-urlencodedURL の末尾にあるクエリ文字列とほぼ同じです。

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

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

于 2010-12-24T12:21:56.823 に答える
555

いつ使用する必要がありますか?

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

私はするつもりだ:

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

HTML5 リファレンス

には3 つの可能性があり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これは、 UTF-8のバイトである であるaωbためです。ωU+03C961 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 localhost 8000; done

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

nc受信したリクエストを出力します。

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

マルチパート/フォームデータ

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 62( aω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、「--」、および「境界」パラメータの値を使用して構築されます。

  • すべてのフィールドは、そのデータの前にいくつかのサブヘッダーを取得します: 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

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

テキスト フィールドに関しては、 や などの通常の印刷可能な文字ab1 バイトで送信されたのに対し、 や などの印刷不可能0xCFな文字はそれぞれ3 バイト0x89を占めていることがわかります。%CF%89

比較

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

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

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

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

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

しかし、テキスト フィールドで見つかった印刷可能な文字の場合は問題ではなく、生成されるオーバーヘッドも少ないため、そのまま使用します。

于 2015-02-07T09:52:03.920 に答える
104

enctype='multipart/form-dataファイルをPOST経由で送信できるようにするエンコーディング タイプです。簡単に言えば、このエンコーディングがないと、ファイルをPOSTで送信できません。

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

于 2010-12-24T12:49:18.400 に答える
92

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

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

  • POSTHTTP メッセージを作成し、すべてのコンテンツをメッセージの本文に入れるようにブラウザに指示します (物事を行うための非常に便利な方法であり、より安全で柔軟でもあります)。
  • GETquerystringでフォーム データを送信します。データの表現と長さに関していくつかの制約があります。

フォームをサーバーに送信する方法を記述する

属性は、メソッド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 ヘッダー フィールドのファイル名を解釈するときに、 受信者のファイル スペース内の
ファイルを誤って上書きしないようにすることが重要です。

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

于 2010-12-24T17:50:10.460 に答える
48

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

于 2013-07-04T09:13:25.253 に答える
8
  • enctype( ENC ode TYPE ) 属性は、サーバーに送信するときにフォームデータをエンコードする方法を指定します。
  • multipart/form-data は enctype 属性の値の 1 つで、ファイルのアップロードを持つフォーム要素で使用されます。マルチパートとは、フォームデータが複数のパートに分割されてサーバーに送信されることを意味します。
于 2015-12-27T01:29:34.253 に答える
2

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

于 2016-03-10T09:29:45.623 に答える