it-swarm.com.de

application / x-www-formular-urlencoded oder mehrteilige / formulardaten?

In HTTP gibt es zwei Möglichkeiten, POST Daten zu senden: application/x-www-form-urlencoded und multipart/form-data. Ich verstehe, dass die meisten Browser nur Dateien hochladen können, wenn multipart/form-data verwendet wird. Gibt es zusätzliche Hinweise zur Verwendung eines der Codierungstypen in einem API-Kontext (kein Browser beteiligt)? Dies könnte z.B. basiert auf:

  • datengröße
  • existenz von Nicht-ASCII-Zeichen
  • existenz auf (nicht verschlüsselten) Binärdaten
  • die Notwendigkeit, zusätzliche Daten (wie Dateiname) zu übertragen

Grundsätzlich habe ich im Web keine formelle Anleitung zur Verwendung der verschiedenen Inhaltstypen gefunden.

1240
max

TL; DR

Zusammenfassung; Wenn Sie binäre (nicht alphanumerische) Daten (oder eine Nutzlast von beträchtlicher Größe) übertragen möchten, verwenden Sie multipart/form-data. Verwenden Sie andernfalls application/x-www-form-urlencoded.


Die MIME-Typen, die Sie erwähnen, sind die beiden Content-Type -Header für HTTP POST -Anforderungen, die Benutzeragenten (Browser) unterstützen müssen. Der Zweck dieser beiden Arten von Anforderungen besteht darin, eine Liste von Name/Wert-Paaren an den Server zu senden. Je nach Art und Menge der übertragenen Daten ist eine der Methoden effizienter als die andere. Um zu verstehen, warum, müssen Sie schauen, was jeder unter der Decke tut.

Bei application/x-www-form-urlencoded besteht der Hauptteil der an den Server gesendeten HTTP-Nachricht im Wesentlichen aus einer riesigen Abfragezeichenfolge - Name/Wert-Paare sind durch das kaufmännische Und (&) und Namen von Werten durch das getrennt Gleichheitszeichen (=). Ein Beispiel hierfür wäre:

MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

Nach der Spezifikation :

[Reservierte und] nicht-alphanumerische Zeichen werden durch% HH, ein Prozentzeichen und zwei Hexadezimalziffern ersetzt, die den ASCII-Code des Zeichens darstellen

Das bedeutet, dass für jedes nicht alphanumerische Byte, das in einem unserer Werte vorhanden ist, drei Bytes erforderlich sind, um es darzustellen. Bei großen Binärdateien ist die Verdreifachung der Nutzlast höchst ineffizient.

Hier kommt multipart/form-data ins Spiel. Bei dieser Methode zum Übertragen von Name/Wert-Paaren wird jedes Paar als "Teil" in einer MIME-Nachricht dargestellt (wie durch andere Antworten beschrieben). Teile werden durch eine bestimmte Zeichenkettengrenze getrennt (speziell ausgewählt, damit diese Zeichenkette in keiner der "Wert" -Nutzlasten vorkommt). Jeder Teil hat seine eigenen MIME-Header wie Content-Type und insbesondere Content-Disposition, die jedem Teil seinen "Namen" geben können. Das Wertstück jedes Name/Wert-Paares ist die Nutzlast jedes Teils der MIME-Nachricht. Die MIME-Spezifikation bietet uns mehr Optionen bei der Darstellung der Nutzlast. Wir können eine effizientere Codierung von Binärdaten wählen, um Bandbreite zu sparen (z. B. Base 64 oder sogar Raw Binary).

Warum nicht die ganze Zeit multipart/form-data verwenden? Bei kurzen alphanumerischen Werten (wie bei den meisten Webformularen) wird der Aufwand für das Hinzufügen aller MIME-Header die Einsparungen durch eine effizientere Binärcodierung erheblich aufwiegen.

1888
Matt Bridges

LESEN SIE AT HIER MINDEST DU DEN ERSTEN ABSATZ!

Ich weiß, dass dies 3 Jahre zu spät ist, aber Matts (akzeptierte) Antwort ist unvollständig und wird Sie irgendwann in Schwierigkeiten bringen. Der Schlüssel hier ist, dass, wenn Sie multipart/form-data verwenden, die Grenze nicht in den Dateidaten erscheinen darf, die der Server schließlich empfängt.

Dies ist kein Problem für application/x-www-form-urlencoded, da es keine Grenze gibt. x-www-form-urlencoded kann auch immer Binärdaten verarbeiten, indem einfach ein beliebiges Byte in drei 7BIT Bytes umgewandelt wird. Ineffizient, aber es funktioniert (und beachten Sie, dass der Kommentar, dass keine Dateinamen und keine Binärdaten gesendet werden können, falsch ist; Sie senden ihn einfach als ein anderes Schlüssel/Wert-Paar).

Das Problem mit multipart/form-data ist, dass das Begrenzungstrennzeichen nicht in den Dateidaten vorhanden sein darf (siehe RFC 2388 ; Abschnitt 5.2 enthält auch eine eher lahme Entschuldigung für das Fehlen eines geeigneten aggregierten MIME-Typs vermeidet dieses Problem).

Auf den ersten Blick hat multipart/form-data in jedem Datei-Upload, binär oder auf andere Weise, keinerlei Wert. Wenn Sie Ihre Grenze nicht richtig wählen, haben Sie irgendwann ein Problem, egal ob Sie Nur-Text oder Binär-Rohdaten senden - der Server findet eine Grenze im falschen Format platzieren, und Ihre Datei wird abgeschnitten, oder die POST wird fehlschlagen.

Der Schlüssel besteht darin, eine Kodierung und eine Begrenzung so zu wählen, dass die von Ihnen ausgewählten Begrenzungszeichen nicht in der kodierten Ausgabe erscheinen können. Eine einfache Lösung besteht darin, base64 zu verwenden (do not use raw binary). In base64 3 werden beliebige Bytes in vier 7-Bit-Zeichen codiert, wobei der Ausgabezeichensatz [A-Za-z0-9+/=] ist (d. H. Alphanumerische Zeichen, '+', '/' oder '='). = ist ein Sonderfall und wird möglicherweise nur am Ende der codierten Ausgabe als einzelner = oder doppelter == angezeigt. Wählen Sie nun Ihre Grenze als 7-Bit-Zeichenfolge ASCII aus, die in der Ausgabe von base64 nicht angezeigt werden kann. Viele Optionen, die Sie im Internet sehen, schlagen bei diesem Test fehl - die MDN-Formulare docs verwenden beispielsweise "blob" als Grenze beim Senden von Binärdaten - nicht gut. Etwas wie "! Blob!" wird niemals in der Ausgabe von base64 erscheinen.

132
EML

Ich glaube nicht, dass HTTP in mehrteiligen oder x-www-form-urlencoded auf POST beschränkt ist. Der Content-Type Header ist orthogonal zur HTTP POST -Methode (Sie können den für Sie passenden MIME-Typ eingeben). Dies ist auch der Fall für typische HTML-darstellungsbasierte Webanwendungen (z. B. JSON-Payload wurde zum Übertragen von Payload für Ajax-Anforderungen sehr beliebt).

In Bezug auf Restful API über HTTP waren die beliebtesten Inhaltstypen, mit denen ich in Kontakt kam, application/xml und application/json.

application/xml:

  • datengröße: XML sehr ausführlich, aber normalerweise kein Problem, wenn Sie die Komprimierung verwenden und glauben, dass der Schreibzugriffsfall (z. B. durch POST oder PUT) viel seltener ist als der Lesezugriff (in vielen Fällen) <3% des gesamten Verkehrs). Selten dort, wo ich die Schreibleistung optimieren musste
  • existenz von Nicht-ASCII-Zeichen: Sie können utf-8 als Codierung in XML verwenden
  • existenz von Binärdaten: Müsste Base64-Codierung verwenden
  • dateinamen-Daten: Sie können dieses innere Feld in XML einkapseln

anwendung/json

  • datengröße: kompakter als XML, Standbild, aber komprimierbar
  • nicht-ASCII-Zeichen: json ist utf-8
  • binärdaten: base64 (siehe auch json-binary-question )
  • dateiname Daten: Kapselung als eigener Feldabschnitt in JSON

binärdaten als eigene Ressource

Ich würde versuchen, binäre Daten als eigenes Asset/Ressource darzustellen. Es fügt einen weiteren Aufruf hinzu, entkoppelt aber das Zeug besser. Beispielbilder:

POST /images
Content-type: multipart/mixed; boundary="xxxx" 
... multipart data

201 Created
Location: http://imageserver.org/../foo.jpg

In späteren Ressourcen können Sie die Binärressource einfach als Link einfügen:

<main-resource>
 ...
 <link href="http://imageserver.org/../foo.jpg"/>
</main-resource>
87
manuel aldana

Ich stimme vielem zu, was Manuel gesagt hat. In der Tat verweisen seine Kommentare auf diese URL ...

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4

... welche Staaten:

Der Inhaltstyp "application/x-www-form-urlencoded" ist ineffizient, um große Mengen von Binärdaten oder Text mit Nicht-ASCII-Zeichen zu senden. Der Inhaltstyp "Multipart/Formulardaten" sollte zum Senden von Formularen verwendet werden, die Dateien, Nicht-ASCII-Daten und Binärdaten enthalten.

Für mich käme es jedoch auf die Unterstützung von Tools/Frameworks an.

  • Mit welchen Tools und Frameworks sollen Ihre API-Benutzer ihre Apps erstellen?
  • Haben sie Frameworks oder Komponenten, mit denen sie eine Methode der anderen vorziehen können?

Wenn Sie eine klare Vorstellung von Ihren Benutzern haben und wissen, wie sie Ihre API verwenden, hilft Ihnen dies bei der Entscheidung. Wenn Sie Ihren API-Benutzern das Hochladen von Dateien erschweren, werden sie wegziehen, und Sie werden viel Zeit für deren Unterstützung aufwenden.

Zweitens wäre dies die Unterstützung des Tools, das SIE zum Schreiben Ihrer API haben, und wie einfach es für Sie ist, einen Upload-Mechanismus über den anderen zu bringen.

29
Martin Peck

Ein kleiner Hinweis von meiner Seite zum Hochladen von HTML5-Canvas-Bilddaten:

Ich arbeite an einem Projekt für eine Druckerei und hatte einige Probleme beim Hochladen von Bildern auf den Server, die von einem HTML5 canvas -Element stammten. Ich hatte mindestens eine Stunde lang Probleme und konnte das Bild nicht richtig auf meinem Server speichern.

Nachdem ich die Option contentType meines jQuery-Ajax-Aufrufs auf application/x-www-form-urlencoded gesetzt hatte, lief alles richtig und die Base64-codierten Daten wurden korrekt interpretiert und erfolgreich als Bild gespeichert.


Vielleicht hilft das jemandem!

2
Torsten Barthel

Wenn Sie Content-Type = x-www-urlencoded-form verwenden müssen, verwenden Sie FormDataCollection NICHT als Parameter: In asp.net Core 2+ verfügt FormDataCollection über keine Standardkonstruktoren, die von Formatters benötigt werden. Verwenden Sie stattdessen IFormCollection:

 public IActionResult Search([FromForm]IFormCollection type)
    {
        return Ok();
    }
1
jahansha