内部でどのようにファイルを送信しますか?
形式はと呼ばれmultipart/form-data
、enctype = 'multipart / form-data'はどういう意味ですか?
私はするつもりだ:
- さらに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ω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。
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 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タイプは、ブラウザによってどのように決定されますか?
application / x-www-form-urlencoded
今変更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
!
比較
多くの場合、ファイルのアップロードには印刷できない文字(画像など)がたくさん含まれていますが、テキストフォームにはほとんど含まれていません。
例から、次のことがわかりました。
したがって、でファイルを送信できたとしても、application/x-www-form-urlencoded
効率が悪いため、送信したくありません。
ただし、テキストフィールドにある印刷可能な文字の場合、問題はなく、オーバーヘッドも少ないので、そのまま使用します。