In HTTP gibt es zwei Möglichkeiten, Daten zu POSTen: application/x-www-form-urlencoded
und multipart/form-data
. Soweit ich weiß, können die meisten Browser Dateien nur hochladen, wenn multipart/form-data
verwendet wird. Gibt es zusätzliche Hinweise, wann einer der Codierungstypen in einem API-Kontext (ohne Browser) verwendet werden sollte? Dies könnte z.B. auf folgender Grundlage erfolgen:
Bisher habe ich im Internet keine formale Anleitung für die Verwendung der verschiedenen Inhaltstypen gefunden.
TL;DR
Zusammenfassung: Wenn Sie binäre (nicht alphanumerische) Daten (oder eine beträchtliche Nutzlast) zu übertragen haben, verwenden Sie multipart/form-data
. Andernfalls verwenden Sie application/x-www-form-urlencoded
.
Bei den von Ihnen erwähnten MIME-Typen handelt es sich um die beiden "Content-Type"-Kopfzeilen für HTTP-POST-Anfragen, die von Benutzer-Agenten (Browsern) unterstützt werden müssen. Der Zweck dieser beiden Anfragetypen besteht darin, eine Liste von Name/Wert-Paaren an den Server zu senden. Je nach Art und Umfang der zu übertragenden Daten ist eine der beiden Methoden effizienter als die andere. Um zu verstehen, warum das so ist, müssen Sie sich ansehen, was die beiden Methoden im Verborgenen tun.
Bei application/x-www-form-urlencoded
ist der Körper der an den Server gesendeten HTTP-Nachricht im Wesentlichen ein riesiger Abfrage-String - Name/Wert-Paare werden durch das kaufmännische Und-Zeichen (&
) getrennt, und Namen werden von Werten durch das Gleichheitszeichen (=
) getrennt. Ein Beispiel hierfür wäre:
MeineVariableEins=WertEins&MeineVariableZwei=WertZwei".
Gemäß der [Spezifikation] (http://www.w3.org/TR/html401/interact/forms.html):
[Reserviert und] nicht-alphanumerische Zeichen werden durch `%HH' ersetzt, ein Prozentzeichen und zwei hexadezimale Ziffern, die den ASCII-Code des Zeichens darstellen
Das bedeutet, dass wir für jedes nicht-alphanumerische Byte in einem unserer Werte drei Bytes benötigen, um es darzustellen. Bei großen Binärdateien ist die Verdreifachung der Nutzlast äußerst ineffizient.
An dieser Stelle kommt multipart/form-data
ins Spiel. Bei dieser Methode der Übermittlung von Name/Wert-Paaren wird jedes Paar als "Teil" in einer MIME-Nachricht dargestellt (wie in anderen Antworten beschrieben). Die Teile werden durch eine bestimmte Zeichenkette getrennt (die speziell so gewählt wird, dass diese Zeichenkette in keinem der "Wert"-Payloads vorkommt). Jeder Teil hat seinen eigenen Satz von MIME-Headern wie Content-Type
und insbesondere Content-Disposition
, die jedem Teil seinen "Namen" geben können. Der Wert eines jeden Name/Wert-Paares ist die Nutzlast eines jeden Teils der MIME-Nachricht. Die MIME-Spezifikation gibt uns mehr Optionen bei der Darstellung der Nutzdaten - wir können eine effizientere Kodierung der Binärdaten wählen, um Bandbreite zu sparen (z. B. Base 64 oder sogar Raw Binary).
Warum nicht immer multipart/form-data
verwenden? Bei kurzen alphanumerischen Werten (wie bei den meisten Webformularen) überwiegt der Overhead, der durch das Hinzufügen aller MIME-Header entsteht, deutlich die Einsparungen durch eine effizientere Binärkodierung.
Ich glaube nicht, dass HTTP auf POST in multipart oder x-www-form-urlencoded beschränkt ist. Der Content-Type Header ist orthogonal zur HTTP-POST-Methode (Sie können den für Sie passenden MIME-Typ angeben). Dies gilt auch für typische Webanwendungen, die auf HTML-Darstellungen basieren (z. B. wurde json payload sehr populär für die Übermittlung von Nutzdaten für Ajax-Anfragen).
In Bezug auf Restful API über HTTP sind die beliebtesten Inhaltstypen, mit denen ich in Berührung kam, application/xml und application/json.
Ich würde versuchen, binäre Daten als eigenes Asset/Ressource darzustellen. Es fügt einen weiteren Aufruf hinzu, aber entkoppelt die Dinge besser. Beispiel Bilder:
POST /images
Inhaltstyp: multipart/mixed; boundary="xxxx"
... mehrteilige Daten
201 Erstellt
Ort: http://imageserver.org/../foo.jpg
In späteren Ressourcen könnten Sie die binäre Ressource einfach als Link einbinden:
Ich stimme vielem zu, was Manuel gesagt hat. In der Tat, seine Kommentare beziehen sich auf diese URL...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... die besagt:
Der Inhaltstyp "application/x-www-form-urlencoded" ist ineffizient für das Senden großer Mengen von Binärdaten oder Text mit Nicht-ASCII-Zeichen. Der Inhaltstyp "multipart/form-data" sollte für die Übermittlung 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.
Wenn Sie sich ein klares Bild von Ihren Nutzern machen und davon, wie sie Ihre API nutzen werden, hilft Ihnen das bei Ihrer Entscheidung. Wenn Sie Ihren API-Benutzern das Hochladen von Dateien erschweren, werden sie abwandern, und Sie werden viel Zeit aufwenden müssen, um sie zu unterstützen.
In zweiter Linie kommt es darauf an, wie gut SIE Ihre API unterstützen und wie einfach es für Sie ist, einen Upload-Mechanismus gegenüber einem anderen zu unterstützen.