回答:
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-data
かapplication/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によって導入され、デバッグのみに役立ちます。仕様から:コンピューターでは確実に解釈できないため、他のツール(ほとんどのブラウザーの開発者ツールのネットワークパネルなど)と組み合わせる方が良いと私は主張しますそのため)。
いつそれを使うべきか
クエンティンの答えは正しいです。multipart/form-data
フォームにファイルのアップロードが含まれている場合は使用し、application/x-www-form-urlencoded
それ以外の場合は省略しenctype
ます。
私はするつもりだ:
ある三つの可能性のためにはenctype
:
application/x-www-form-urlencoded
multipart/form-data
(スペックはRFC7578を指します)text/plain
。これは「コンピュータで確実に解釈できない」ため、本番環境で使用することはできません。詳しくは調査しません。各メソッドの例を見ると、それらがどのように機能するか、そしていつそれぞれを使用すべきかが明らかになります。
以下を使用して例を作成できます。
nc -l
またはECHOサーバー:GET / POSTリクエストを受け入れるHTTPテストサーバーフォームを最小限の.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ω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ω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、nc
BSD 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ωb
UTF-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;
、フィールドはname
、filename
データが続きます。
サーバーは次の境界文字列までデータを読み取ります。ブラウザはどのフィールドにも表示されない境界を選択する必要があるため、リクエスト間で境界が異なる場合があります。
一意の境界があるため、データのエンコードは必要ありません。バイナリデータはそのまま送信されます。
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タイプはブラウザによってどのように決定されますか?
今変更enctype
しapplication/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バイトで送信された0xCF
と0x89
取り上げた3バイトごと:%CF%89
!
多くの場合、ファイルのアップロードには印刷できない文字(画像など)がたくさん含まれていますが、テキストフォームにはほとんど含まれていません。
例から、次のことがわかりました。
multipart/form-data
:数バイトの境界オーバーヘッドをメッセージに追加し、メッセージの計算にある程度の時間を費やす必要がありますが、各バイトを1バイトで送信します。
application/x-www-form-urlencoded
:フィールドごとに1バイト境界(&
)がありますが、印刷できない文字ごとに3倍の線形オーバーヘッド係数が追加されます。
したがって、でファイルを送信できたとしても、application/x-www-form-urlencoded
効率が悪いため、送信したくありません。
ただし、テキストフィールドにある印刷可能な文字の場合、問題はなく、オーバーヘッドも少ないので、そのまま使用します。
%CF
は3バイト長です:%
、C
およびF
:-)人間が読めるようにするストーリー。
nc
両方受け入れない-l
と-p
同時に引数を。しかし、これは私にとってはうまくいきます:while true; do printf '' | nc -l 8000; done
。
Content-Type
いない小さいが重要な点は、で指定された境界のハイフン(--
)が2つ少ないことです。つまり、実際にメッセージ本文で境界を使用する場合は、接頭辞としてを付ける必要があります--
。また、最後の境界には接尾辞としてを付ける必要がありますが--
、これは簡単にわかります。stackoverflow.com/questions/3508252/…を
enctype='multipart/form-data
POSTを介してファイルを送信できるようにするエンコードタイプです。簡単に言うと、このエンコードがなければ、ファイルをPOST経由で送信することはできません。
ユーザーがフォームを介してファイルをアップロードできるようにする場合は、このenctypeを使用する必要があります。
multipart/form-data
非バイナリファイルの送信に使用できますが、非効率的です。application/x-www-form-urlencoded
非バイナリデータを送信するには、使用するのが正しい方法だと思いますが、非バイナリファイルの経験が豊富な方は、私を修正する必要があるかもしれません。
multipart/form-data
ファイルの送信に使用する主な利点は、ファイルがフロントエンドとバックエンドの両方で自動的に機能することです。特別な処理を行う必要はありません。テキストのみを含む必要がある場合でも、すべてのファイルはバイナリです。 application/x-www-form-urlencoded
添付ファイルなしでフォームをPOSTする標準的な方法です。multipart/form-data
添付ファイルのあるフォームをPOSTする標準的な方法です。(また、サーバーやクライアント間の通信に一般的なapplication/json
やなど、他にも多数のエンコーディングapplication/json-patch+json
があります。)
multipart/form-data
。あなたがすることはできませんやっていることはJavaScriptをせずに、通常のHTMLフォーム送信を使用してそれを行うです。フォームを使用するように設定することmultipart/form-data
は、JavaScriptを使用せずにファイルをPOSTするためにHTMLが提供する唯一のメカニズムです。これは答えが十分に明確ではないように感じます。そして、世間知らずな読者multipart/form-data
は、ファイルを送信できないとHTTPの制限であると考えるかもしれません。そうではありません。
フォームを送信するときは、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ヘッダーフィールドのファイル名を解釈するときに、
受信者のファイルスペース内のファイルを誤って上書きしないことが重要です。
これは、あなたが開発者であり、サーバーがユーザーによって送信されたフォームを処理する場合に関係し、最終的に機密情報が含まれる可能性があります。
enctype
です。私はそれが文字通りから知っているmultipart/form-data
RFCが、それでもそれは、データは次のように送られているかどうかに完全に直交しているフォーム提出に関するセキュリティ上の考慮事項の任意のダンプだapplication/x-www-form-urlencoded
かをmultipart/form-data
。
フォームを使用してファイルのコンテンツをURLパラメータ内に配置することはできないため、method属性をPOSTに設定します。
データは複数の部分に分割されるため、enctypeの値をmultipart / form-dataに設定します。各ファイルに1つと、一緒に送信されるフォーム本文のテキストに1つです。
POST
は、フォームを介してファイルを送信するのに十分である可能性が高く、追加multipart/form-data
は漠然とした方法でのボーナスにすぎないことを意味します。そうではありません。ほとんどのファイルでは、絶対にを使用する必要がありますmultipart/form-data
。
<head>
と<body>
は無関係と混乱です。
enctype属性は、フォームデータをサーバーに送信するときにエンコードする方法を指定します。
enctype属性は、method = "post"の場合にのみ使用できます。
文字はエンコードされません。この値は、ファイルアップロードコントロールがあるフォームを使用している場合に必要です。
multipart/form-data
。それもかなり不明確です。「文字がエンコードされていません」という文はどういう意味ですか?-1。