Wie wird die Datei intern versendet?
Das Format heißt multipart/form-data
wie gefragt bei: Was bedeutet enctype='multipart/form-data'?
Das werde ich tun:
- einige weitere HTML5-Referenzen hinzufügen
- erklären warum er hat Recht mit einem Beispiel für die Übermittlung eines Formulars
HTML5-Referenzen
Es gibt drei Möglichkeiten para enctype
:
Wie man die Beispiele generiert
Sobald Sie ein Beispiel für jede Methode sehen, wird klar, wie sie funktionieren und wann Sie sie einsetzen sollten.
Sie können Beispiele erstellen:
Speichern Sie das Formular in einem minimalen .html
archivo:
<!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>
Wir setzen den Standard-Textwert auf aωb
was bedeutet ab
denn es U+03C9
das sind die Bytes 61 CF 89 62
in UTF-8.
Erstellen Sie Dateien zum Hochladen:
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
Starten Sie unseren kleinen Echo-Server:
while true; do printf '' | nc -l 8000 localhost; done
Öffnen Sie den HTML-Code in Ihrem Browser, wählen Sie die Dateien aus, klicken Sie auf "Senden" und überprüfen Sie das Terminal.
nc
druckt die erhaltene Anfrage.
Getestet am: Ubuntu 14.04.3, nc
BSD 1.105, Firefox 40.
multipart/form-data
Firefox gesendet:
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"
ab
-----------------------------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
ab
-----------------------------735323031399963166993862150--
Für die Binärdatei und das Textfeld werden die Bytes 61 CF 89 62
( ab
in UTF-8) werden wörtlich gesendet. Sie können dies überprüfen mit nc -l localhost 8000 | hd
die besagt, dass die Bytes:
61 CF 89 62
gesendet wurden ( 61
== 'a' und 62
== 'b').
Es ist also klar, dass:
-
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
setzt den Inhaltstyp auf multipart/form-data
und sagt, dass die Felder durch die angegebene boundary
String.
Aber beachten Sie, dass die:
boundary=---------------------------735323031399963166993862150
hat zwei Daddeln weniger --
als die eigentliche Barriere
-----------------------------735323031399963166993862150
Dies liegt daran, dass die Norm vorschreibt, dass die Begrenzung mit zwei Bindestrichen beginnen muss --
. Die anderen Striche scheinen nur die Art und Weise zu sein, wie Firefox die willkürliche Grenze implementiert hat. RFC 7578 erwähnt eindeutig, dass diese beiden führenden Bindestriche --
sind erforderlich:
4.1. "Boundary" Parameter von multipart/form-data
Wie bei anderen mehrteiligen Typen werden die Teile mit einem Begrenzungszeichen abgegrenzt, das aus CRLF, "--" und dem Wert des des Parameters "Begrenzung".
anwendung/x-www-form-urlencoded
Ändern Sie nun die enctype
a application/x-www-form-urlencoded
, laden Sie den Browser neu und senden Sie ihn erneut ab.
Firefox gesendet:
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
Offensichtlich wurden die Dateidaten nicht gesendet, sondern nur die Basisnamen. Dies kann also nicht für Dateien verwendet werden.
Was das Textfeld betrifft, so sehen wir, dass übliche druckbare Zeichen wie a
y b
wurden in einem Byte gesendet, während nicht druckbare Zeichen wie 0xCF
y 0x89
aufgegriffen 3 Bytes jeder: %CF%89
!
Vergleich
Datei-Uploads enthalten oft viele nicht druckbare Zeichen (z. B. Bilder), während dies bei Textformularen fast nie der Fall ist.
Anhand der Beispiele haben wir gesehen, dass:
-
multipart/form-data
: fügt der Nachricht ein paar Bytes Rand-Overhead hinzu und muss einige Zeit für die Berechnung aufwenden, sendet aber jedes Byte in einem Byte.
-
application/x-www-form-urlencoded
: hat eine einzelne Byte-Grenze pro Feld ( &
), sondern fügt eine linear Zuschlagsfaktor von 3x für jedes nicht druckbare Zeichen.
Selbst wenn wir also Dateien mit application/x-www-form-urlencoded
Wir würden das nicht wollen, weil es so ineffizient ist.
Für druckbare Zeichen in Textfeldern spielt dies jedoch keine Rolle und verursacht weniger Overhead, so dass wir es einfach verwenden.
0 Stimmen
Ich habe schon lange keinen Sniffer mehr benutzt, aber wenn Sie sehen wollen, was in Ihrer Anfrage gesendet wird (da sie an den Server gerichtet ist, ist es eine Anfrage), dann schnüffeln Sie. Diese Frage ist zu weit gefasst. SO ist mehr für spezifische Programmierfragen.
0 Stimmen
...als Schnüffler, . ist die Waffe meiner Wahl. Sie können sogar Ihre eigenen Testanfragen erstellen, um zu sehen, wie sie veröffentlicht werden.
0 Stimmen
Für Interessierte, siehe auch "
MAX_FILE_SIZE
in PHP - wozu das Ganze?" auf stackoverflow.com/q/1381364/6329510 Stimmen
Ich finde MAX_FILE_SIZE seltsam, denn ich kann mein HTML in Chrome auf 100000000 ändern, bevor ich es poste, damit es einen besseren Wert liefert. Entweder 1. haben es in einem Cookie mit einem sicheren Hash über Salz so Cookie, wenn geändert, Server kann validieren und werfen Ausnahme (wie Webpieces oder playframework beide tun) oder eine Art von Formular-Validierung, dass die Dinge nicht geändert haben. @0xSina