Was bedeutet enctype = 'multipart / form-data'?

Antworten:

1570

Wenn Sie eine POST-Anfrage stellen, müssen Sie die Daten, die den Hauptteil der Anfrage bilden, auf irgendeine Weise codieren.

HTML-Formulare bieten drei Codierungsmethoden.

  • application/x-www-form-urlencoded (der Standard)
  • multipart/form-data
  • text/plain

Es wurde daran gearbeitet, etwas hinzuzufügen application/json , aber das wurde aufgegeben.

(Andere Codierungen sind mit HTTP-Anforderungen möglich, die mit anderen Mitteln als der Übermittlung von HTML-Formularen generiert wurden. JSON ist ein gängiges Format für die Verwendung mit Webdiensten, und einige verwenden weiterhin SOAP.)

Die Besonderheiten der Formate spielen für die meisten Entwickler keine Rolle. Die wichtigen Punkte sind:

  • Niemals benutzen text/plain.

Wenn Sie clientseitigen Code schreiben:

  • Verwenden multipart/form-dataSie diese Option, wenn Ihr Formular <input type="file">Elemente enthält
  • sonst können Sie verwenden , multipart/form-dataoder application/x-www-form-urlencodedaber application/x-www-form-urlencodedwird effizienter

Wenn Sie serverseitigen Code schreiben:

  • Verwenden Sie eine vorab geschriebene Formularbearbeitungsbibliothek

Die meisten (wie Perls CGI->paramoder die von PHPs$_POST PHPs Superglobal herausgestellt wurden) kümmern sich um die Unterschiede für Sie. Versuchen Sie nicht, die vom Server empfangenen Roheingaben zu analysieren.

Manchmal finden Sie eine Bibliothek, die nicht beide Formate verarbeiten kann. Die beliebteste Bibliothek von Node.js für die Verarbeitung von Formulardaten ist der Body-Parser, der keine mehrteiligen Anforderungen verarbeiten kann (aber eine Dokumentation enthält, in der einige Alternativen empfohlen werden).


Wenn Sie eine Bibliothek zum Parsen oder Generieren der Rohdaten schreiben (oder debuggen), müssen Sie sich Gedanken über das Format machen. Vielleicht möchten Sie es auch aus Interesse wissen.

application/x-www-form-urlencoded ist mehr oder weniger dasselbe wie eine Abfragezeichenfolge am Ende der URL.

multipart/form-dataist wesentlich komplizierter, ermöglicht jedoch die Aufnahme ganzer Dateien in die Daten. Ein Beispiel für das Ergebnis finden Sie in der HTML 4-Spezifikation .

text/plainwird durch HTML 5 eingeführt und ist nur zum Debuggen nützlich - aus der Spezifikation : Sie sind vom Computer nicht zuverlässig interpretierbar - und ich würde argumentieren, dass die anderen in Kombination mit Tools (wie das Netzwerkpanel in den Entwicklertools der meisten Browser) besser sind dafür).

QUentin
quelle
5
@ Quentin Entschuldigung, was wird ein wahrscheinliches Problem sein, wenn wir mehrteilig für alle Formulare verwenden? mit und mit Dateien.
Webinan
12
Für GET-Formulare ist dies nicht sinnvoll, und die Dateigröße von Anforderungen wird größer.
Quentin
@Quentin werden mehrteilige Formulardaten standardmäßig als Stream gesendet?
Growler
Steht die enc in enctype für etwas?
Philip Rego
1
"HTML-Formulare bieten drei Methoden der ENC- Codierung"
Quentin
449

wann sollen wir es benutzen

Die Antwort von Quentin ist richtig: Verwenden Sie multipart/form-datadiese Option, wenn das Formular einen Datei-Upload enthält, application/x-www-form-urlencodedandernfalls die Standardeinstellung, wenn Sie sie weglassen enctype.

Ich werde:

  • Fügen Sie weitere HTML5-Referenzen hinzu
  • Erklären Sie, warum er Recht hat, mit einem Beispiel zum Senden eines Formulars

HTML5-Referenzen

Es gibt drei Möglichkeiten für enctype:

So generieren Sie die Beispiele

Sobald Sie ein Beispiel für jede Methode sehen, wird klar, wie sie funktionieren und wann Sie jede verwenden sollten.

Sie können Beispiele erstellen mit:

Speichern Sie das Formular in einer minimalen .htmlDatei:

<!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>

Wir setzen den Standardtextwert auf a&#x03C9;b, was bedeutet, aωbdass ωis U+03C9die Bytes 61 CF 89 62in UTF-8 sind.

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

Führen Sie unseren kleinen Echoserver aus:

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 empfangene Anfrage.

Getestet am: Ubuntu 14.04.3, ncBSD 1.105, Firefox 40.

mehrteilige / Formulardaten

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"

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--

Für die Binärdatei und das Textfeld werden die Bytes 61 CF 89 62( aωbin UTF-8) buchstäblich gesendet. Sie könnten das mit überprüfen nc -l localhost 8000 | hd, was besagt, dass die Bytes:

61 CF 89 62

wurden gesendet ( 61== 'a' und62 == 'b').

Daher ist es klar, dass:

  • Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150Setzt den Inhaltstyp auf multipart/form-dataund gibt an, dass die Felder durch die angegebene boundaryZeichenfolge getrennt sind.

    Beachten Sie jedoch, dass die:

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

    hat zwei weniger Dadhes --als die eigentliche Barriere

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

    Dies liegt daran, dass der Standard erfordert, dass die Grenze mit zwei Strichen beginnt --. Die anderen Striche scheinen genau so zu sein, wie Firefox die willkürliche Grenze implementiert hat. In RFC 7578 wird klar erwähnt, dass diese beiden führenden Striche --erforderlich sind:

    4.1. "Grenze" Parameter von mehrteiligen / Formulardaten

    Wie bei anderen mehrteiligen Typen werden die Teile durch einen Begrenzungsbegrenzer begrenzt, der unter Verwendung von CRLF, "-" und dem Wert des Parameters "Grenze" erstellt wird.

  • Jedes Feld erhält einige Unterüberschriften vor seinen Daten : Content-Disposition: form-data;, das Feld name, dasfilename , gefolgt von den Daten.

    Der Server liest die Daten bis zur nächsten Grenzzeichenfolge. Der Browser muss eine Grenze auswählen, die in keinem der Felder angezeigt wird. Aus diesem Grund kann die Grenze zwischen den Anforderungen variieren.

    Da wir die eindeutige Grenze haben, ist keine Codierung der Daten erforderlich: Binärdaten werden unverändert gesendet.

    TODO: Was ist die optimale Grenzgröße ( log(N)ich wette) und Name / Laufzeit des Algorithmus, der sie findet? Gefragt unter: /cs/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences

  • Content-Type wird automatisch vom Browser ermittelt.

    Wie es genau bestimmt wird, wurde gefragt: Wie wird der MIME-Typ einer hochgeladenen Datei vom Browser bestimmt?

application / x-www-form-urlencoded

Ändern Sie nun das enctypein application/x-www-form-urlencoded, laden Sie den Browser neu und senden Sie es erneut.

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 nicht die Dateidaten gesendet, sondern nur die Basisnamen. Dies kann also nicht für Dateien verwendet werden.

Wie für das Textfeld ein , so sehen wir , dass die üblichen druckbare Zeichen wie aund bwurden in einem Byte, während nicht-druckbaren wie geschickt 0xCFund 0x89nahmen 3 Bytes je: %CF%89!

Vergleich

Das Hochladen von Dateien enthält häufig viele nicht druckbare Zeichen (z. B. Bilder), während Textformulare dies fast nie tun.

Aus den Beispielen haben wir gesehen, dass:

  • multipart/form-data: Fügt der Nachricht ein paar Bytes Boundary Overhead hinzu und muss einige Zeit mit der Berechnung verbringen, sendet jedoch jedes Byte in einem Byte.

  • application/x-www-form-urlencoded: hat eine einzelne Bytegrenze pro Feld ( &), fügt jedoch für jedes nicht druckbare Zeichen einen linearen Overhead-Faktor von 3x hinzu .

Selbst wenn wir Dateien mit senden könnten, application/x-www-form-urlencodedwürden wir dies nicht wollen, weil es so ineffizient ist.

Für druckbare Zeichen in Textfeldern spielt dies jedoch keine Rolle und erzeugt weniger Overhead. Daher verwenden wir es einfach.

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
quelle
3
@ Khanna111 %CFist 3 Bytes lang: %, Cund F:-) Geschichte es für Menschen lesbaren machen.
Ciro Santilli 6 病毒 审查 六四 事件 6
6
ncAkzeptiert unter OS X nicht gleichzeitig -ldie -pArgumente und die Argumente. Aber das funktioniert bei mir : while true; do printf '' | nc -l 8000; done.
PhilipS
4
Ein kleiner, aber wichtiger Punkt, der nicht erwähnt wird, ist, dass die in angegebene Grenze Content-Typezwei Bindestriche ( --) weniger hat, dh wenn Sie die Grenze im Nachrichtentext tatsächlich verwenden, müssen Sie ihr ein Präfix voranstellen --. Auch die letzte Grenze muss mit einem Suffix versehen werden --, aber das ist leicht zu bemerken. Siehe stackoverflow.com/questions/3508252/…
Bernard
1
Soweit ich das beurteilen kann, besteht der Sinn, ANY DASHES überhaupt in die Grenze zu setzen, darin, es unmöglich zu machen, die Syntax der Anfrage mit dem Auge zu überprüfen. Bitte verwenden Sie sie nicht in Ihren Grenzmarken.
Dewi Morgan
1
@ DewiMorgan Du hast vollkommen recht. Ich habe den Beitrag bearbeitet und die Bindestriche aus der Begrenzungszeichenfolge entfernt.
Max
91

enctype='multipart/form-dataist ein Codierungstyp, mit dem Dateien über einen POST gesendet werden können . Ganz einfach, ohne diese Codierung können die Dateien nicht über POST gesendet werden .

Wenn Sie einem Benutzer erlauben möchten, eine Datei über ein Formular hochzuladen, müssen Sie diesen Enctype verwenden .

Matt Asbury
quelle
Also .. wenn die Datei keine Binärdatei ist, können wir dann ohne diese arbeiten?
Yugal Jindle
Soweit ich multipart/form-dataweiß , können Sie nicht-binäre Dateien senden, dies ist jedoch ineffizient. Ich glaube, die Verwendung application/x-www-form-urlencodedist der richtige Weg, um nicht-binäre Daten zu senden, aber jemand mit mehr Erfahrung mit nicht-binären Dateien muss mich möglicherweise korrigieren.
Matt Asbury
11
Der Hauptvorteil multipart/form-databeim Senden einer Datei besteht darin, dass sie sowohl im Frontend als auch im Backend automatisch funktioniert. Sie müssen keine spezielle Behandlung durchführen. Alle Dateien sind binär, auch wenn sie nur Text enthalten sollen. application/x-www-form-urlencodedist die Standardmethode zum POSTEN eines Formulars ohne angehängte Dateien. multipart/form-dataist die Standardmethode zum POSTEN eines Formulars mit angehängten Dateien. (Es gibt auch zahlreiche andere Codierungen, wie application/jsonund application/json-patch+json, die für die Kommunikation zwischen Server und Client üblich sind.)
Daniel Luna
6
Es ist erwähnenswert, dass Sie Ihr Bild mit base64 codieren und als einfache Zeichenfolgendaten senden können.
James
3
Weiter zu @ Prosperos Kommentar oben: Sie können Dateien absolut per POST senden, ohne sie zu verwenden multipart/form-data. Was Sie nicht tun können, ist dies mit einem normalen HTML-Formular ohne JavaScript zu tun. Das Festlegen eines zu verwendenden Formulars multipart/form-dataist der einzige von HTML bereitgestellte Mechanismus, mit dem Sie Dateien ohne Verwendung von JavaScript POSTEN können. Ich bin der Meinung, dass dies in der Antwort nicht klar genug ist und dass ein naiver Leser denken könnte, dass die Unfähigkeit, Dateien ohne zu senden, multipart/form-dataeine Einschränkung von HTTP darstellt . das ist nicht der Fall.
Mark Amery
81

Wenn Sie ein Formular senden, weisen Sie Ihren Browser an, über das HTTP-Protokoll eine Nachricht im Netzwerk zu senden, die ordnungsgemäß in eine TCP / IP-Protokollnachrichtenstruktur eingebunden ist. Eine HTML-Seite bietet eine Möglichkeit, Daten an den Server zu senden: mithilfe von <form>s.

Wenn ein Formular gesendet wird, wird eine HTTP-Anforderung erstellt und an den Server gesendet. Die Nachricht enthält die Feldnamen im Formular und die vom Benutzer eingegebenen Werte. Diese Übertragung kann mit POSToder GET HTTP-Methoden erfolgen .

  • POST Weist Ihren Browser an, eine HTTP-Nachricht zu erstellen und den gesamten Inhalt in den Nachrichtentext einzufügen (eine sehr nützliche Methode, sicherer und auch flexibler).
  • GETsendet die Formulardaten im Querystring . Es gibt einige Einschränkungen hinsichtlich der Datendarstellung und -länge.

Angabe, wie Sie Ihr Formular an den Server senden

Das Attribut enctypeist nur bei Verwendung der POSTMethode sinnvoll . Wenn angegeben, weist es den Browser an, das Formular zu senden, indem sein Inhalt auf eine bestimmte Weise codiert wird. Aus MDN - Formular enctype :

Wenn der Wert des Methodenattributs post ist, ist enctype der MIME-Inhaltstyp, mit dem das Formular an den Server gesendet wird.

  • application/x-www-form-urlencoded: Dies ist die Standardeinstellung. Beim Senden des Formulars werden alle Namen und Werte erfasst und die URL-Codierung für die endgültige Zeichenfolge durchgeführt.
  • multipart/form-data: Zeichen sind NICHT codiert. Dies ist wichtig, wenn das Formular über ein Steuerelement zum Hochladen von Dateien verfügt. Sie möchten die Datei binär senden und dies stellt sicher, dass der Bitstrom nicht geändert wird.
  • text/plain: Leerzeichen werden konvertiert, es wird jedoch keine weitere Codierung durchgeführt.

Sicherheit

Beim Senden von Formularen können einige Sicherheitsbedenken auftreten, wie in RFC 7578, Abschnitt 7: Mehrteilige Formulardaten - Sicherheitsüberlegungen angegeben :

Jede Formularverarbeitungssoftware sollte vom Benutzer bereitgestellte Formulardaten
mit Sensibilität behandeln, da sie häufig vertrauliche oder persönlich
identifizierende Informationen enthält. In Webbrowsern werden häufig Funktionen zum automatischen Ausfüllen von Formularen verwendet. Diese können verwendet werden, um Benutzer dazu zu
verleiten, unwissentlich vertrauliche Informationen zu senden, wenn sie ansonsten
harmlose Aufgaben ausführen. Multipart- / Formulardaten bieten keine Funktionen
zur Überprüfung der Integrität, zur Gewährleistung der Vertraulichkeit, zur Vermeidung von
Verwirrung der Benutzer oder zu anderen Sicherheitsfunktionen. Diese Bedenken müssen in
den Anträgen zum Ausfüllen von Formularen und zum Interpretieren von Formulardaten berücksichtigt werden .

Anträge, die Formulare empfangen und verarbeiten, müssen darauf achten, dass keine Daten an die anfordernde Formularverarbeitungssite zurückgesendet werden, die nicht zum Senden vorgesehen war.

Bei der Interpretation des Dateinamens des Content-
Disposition-Headerfelds ist es wichtig, dass Dateien im
Dateibereich des Empfängers nicht versehentlich überschrieben werden .

Dies betrifft Sie, wenn Sie Entwickler sind und Ihr Server von Benutzern übermittelte Formulare verarbeitet, die möglicherweise vertrauliche Informationen enthalten.

Andry
quelle
1
Das Thema Sicherheit nach der letzten Bearbeitung ist für die Frage, was zu enctypetun ist, irrelevant . Ich weiß, dass es buchstäblich aus dem multipart/form-dataRFC stammt, aber es ist dennoch ein willkürlicher Speicherauszug von Sicherheitsüberlegungen zum Senden von Formularen, die völlig orthogonal dazu sind, ob Daten als application/x-www-form-urlencodedoder gesendet werden multipart/form-data.
Mark Amery
38

enctype='multipart/form-data'bedeutet, dass keine Zeichen codiert werden. Aus diesem Grund wird dieser Typ beim Hochladen von Dateien auf den Server verwendet.
Wird multipart/form-dataverwendet, wenn für ein Formular Binärdaten wie der Inhalt einer Datei hochgeladen werden müssen

GP Singh
quelle
8

Setzen Sie das Methodenattribut auf POST, da der Dateiinhalt nicht mithilfe eines Formulars in einen URL-Parameter eingefügt werden kann.

Setzen Sie den Wert von enctype auf multipart / form-data, da die Daten in mehrere Teile aufgeteilt werden, einen für jede Datei und einen für den Text des Formularkörpers, der mit ihnen gesendet werden kann.

sandig
quelle
Dies impliziert, dass dies POSTwahrscheinlich ausreicht, um eine Datei über ein Formular einzureichen, und dass das Hinzufügen multipart/form-datanur auf vage Weise nur ein Bonus ist. Das ist nicht der Fall. Die meisten Dateien müssen unbedingt verwendet werden multipart/form-data.
underscore_d
1
  • Das Attribut enctype ( ENC ode TYPE ) gibt an, wie die Formulardaten beim Senden an den Server codiert werden sollen.
  • Multipart / Formulardaten sind einer der Werte des Attributs enctype, das in Formularelementen verwendet wird, für die eine Datei hochgeladen wurde. Mehrteilig bedeutet, dass Formulardaten in mehrere Teile aufgeteilt und an den Server gesendet werden.
Premraj
quelle
5
Ich glaube, Enctype steht nicht für Verschlüsselungstyp. Auf dieser Ebene ist keine Verschlüsselung erforderlich. Meine Vermutung ist entweder Codierungstyp oder beiliegender Typ. Aber es ist sicherlich kein Verschlüsselungstyp.
Yeo
1
Ihr letzter Aufzählungspunkt hier über <head>und <body>ist irrelevant und verwirrend.
Mark Amery
0

Normalerweise ist dies der Fall, wenn Sie ein POST-Formular haben, für das ein Datei-Upload als Daten erforderlich ist. Dadurch wird dem Server mitgeteilt, wie die übertragenen Daten codiert werden. In diesem Fall wird es nicht codiert, da es nur übertragen und hochladen wird die Dateien auf den Server, wie zum Beispiel beim Hochladen eines Bildes oder eines PDFs

Eric
quelle
-3

Das Attribut enctype gibt an, wie die Formulardaten beim Senden an den Server codiert werden sollen.

Das enctype-Attribut kann nur verwendet werden, wenn method = "post".

Es werden keine Zeichen codiert. Dieser Wert ist erforderlich, wenn Sie Formulare verwenden, die über ein Steuerelement zum Hochladen von Dateien verfügen

Von W3Schools

Rishad
quelle
2
Dieses Zitat erwähnt nicht einmal multipart/form-data. Es ist auch ziemlich unklar; Was bedeutet der Satz "Keine Zeichen sind codiert" überhaupt? -1.
Mark Amery