Request-Header Content-Type und XHR
Email
- ajax
1 Rolf B0 Email0 1unitedpower- troll
0 Rolf B
Der Default für den Enctype ist application/x-www-form-urlencoded
und mit dem Code
var xhr = new XMLHttpRequest();
xhr.open('POST','/');
xhr.send();
wird auch kein Content-Type-Header gesendet. Jeder RFCkonforme Parser nimmt daher in solchen Fällen den Default an und parst die Daten dem DefaultEnctype entsprechend.
Nun ist es jedoch so, daß mit
xhr.send('x=Y&a=b');
spontan ein Content-Type: text/plain; charset=utf-8
gesendet wird, das natürlich 1. Blödsinn ist und 2. der Server damit die Parameter gar nicht parsen kann.
Nun könnte ich ja mit xhr.setRequestHeader('Content-Type',' application/x-www-form-urlencoded')
die Sache richtig stellen aber das ist mir zuviel Tipparbeit. Zumal das in HTLM-Formularen wohl kaum auch jemand macht.
Gibt es eine kurze Möglichkeit dem xhr
beizubringen, daß er keinen solchen Header sendet?
MFG
Hallo Email,
Der Default für den Enctype ist application/x-www-form-urlencoded
Das ist der Default für das enctype-Attribut des Form-Elements. XMLHttpRequest tickt anders.
Jeder RFCkonforme Parser nimmt daher in solchen Fällen den Default an
Der Default für das HTTP Protokoll - wenn der Content-Type Header fehlt - ist gemäß RFC2616 application/octet-stream, und HTTP Receivern wird es erlaubt, den Inhalt zu beschnuppern um auf eine bessere Idee zu kommen.
Welchen RFC hast Du jetzt gemeint?
xhr.send('x=Y&a=b');
(setzt) spontan Content-Type: text/plain; charset=utf-8 (...), das natürlich 1. Blödsinn ist
Nein, das ist kein Blödsinn. Du sendest einen String (Web IDL Typ USVString). Der Browser verhält sich damit gemäß der Spec, siehe 4.5.6 send() und 5.2 Body mixin.
Dass die send-Methode den Inhalt eines Strings beschnuppert und daraus einen Content-Type errät, gestattet die Spec nicht.
Wenn Du urlencoded willst, ohne selber den Content-Type zu setzen, dann sende ein URLSearchParams Objekt. Das wird Spec-gemäß mit dem von Dir gewünschten Content-Type gesendet.
Aber wenn Du schon den urlencoded String handgeschnitzt hast, dann mach Dir aus den Spänen auch noch einen Presskuchen in application/x-www-form-urlencoded
Form. Das fällt dann in der Library, die das hoffentlich sauber kapselt, auch nicht mehr ins Gewicht.
Rolf
xhr.send('x=Y&a=b');
(setzt) spontan Content-Type: text/plain; charset=utf-8 (...), das natürlich 1. Blödsinn istNein, das ist kein Blödsinn. Du sendest einen String (Web IDL Typ USVString).
Dieser String entspricht dem Content-Type application/x-www-form-urlencoded
Der Browser verhält sich damit gemäß der Spec, siehe 4.5.6 send() und 5.2 Body mixin.
wobei dieser Enctype selbstverständlich auch als Messagebody per POST gesendet werden kann. Was ein Browser auch tut ohne einen Content-Type header dazuzutun.
Dass die send-Methode den Inhalt eines Strings beschnuppert und daraus einen Content-Type errät, gestattet die Spec nicht.
Das verlange ich auch gar nicht.
Wenn Du urlencoded willst, ohne selber den Content-Type zu setzen, dann sende ein URLSearchParams Objekt. Das wird Spec-gemäß mit dem von Dir gewünschten Content-Type gesendet.
Nein, wird sie nicht. Auch damit wird text/plain
gesendet.
Und meine Frage ist immernoch, wie ich dem xhrObjekt diese Sponatinät abgewöhnen kann. Also dem xhr Objekt beizubringen daß es sich so verhält wie der Browser in dem es lebt.
MFG
Nein, wird sie nicht. Auch damit wird
text/plain
gesendet.
><((((*>
Hallo Email,
Nein, wird sie nicht. Auch damit wird text/plain gesendet.
Dann machen Du oder dein Browser was falsch. Bei mir wird application/x-www-form-urlencoded;charset=UTF-8 gesendet.
const request = new XMLHttpRequest();
request.open("POST","dummy.dat");
request.addEventListener('load', ...);
const sp = new URLSearchParams();
sp.append("hello", "3");
sp.append("world", "4");
request.send(sp);
Rolf
Aha. Du übergibst das Objekt sp
und nicht den String. Wenn ich das Objekt übergebe funktionierts bei mir auch wie gewünscht.
MFG
Hallo Watson,
elementar!
Rolf
Nunja, wenn xhr.send(obj) nicht den String sondern das URLSearchParamObject bekommt wird schon der richtige Header gesendet.
Aber Eigentlich sollte xhr ja gar keinen Content-Type Header senden. Und schon gar nicht den Enctype selbst erraten. Dafür gibts ja den Default.
Danke und Gruß.
Nunja, wenn xhr.send(obj) nicht den String sondern das URLSearchParamObject bekommt wird schon der richtige Header gesendet.
Aber Eigentlich sollte xhr ja gar keinen Content-Type Header senden.
Doch. Aus RFC 7231:
A sender that generates a message containing a payload body SHOULD generate a Content-Type header field in that message unless the intended media type of the enclosed representation is unknown to the sender.
Hervorhebung von mir.
Und schon gar nicht den Enctype selbst erraten.
Es wird nichts geraten, das Verhalten ist so spezifiziert.
Du müsstest dir einfach mal die Mühe machen, den Links zu folgen und die Spezifikationen zu lesen, die dir nahegelegt werden.
Und schon gar nicht den Enctype selbst erraten.
Es wird nichts geraten, das Verhalten ist so spezifiziert.
xhr errät aus x=y
den Content-Type text/plain; charset=UTF-8
und sendet diesen Header spontan im Request.
Ein HTML <form method="POST">, also ohne Angabe des Enctype sendet den Default Content-Type mit demselben Payload x=y
.
Man könnte also durchaus erwarten, daß sich xhr genauso wie ein Browser verhält, was jedoch definitiv nicht der Fall ist. Siehe Spezifikation (Link weiter oben).
Du müsstest dir einfach mal die Mühe machen, den Links zu folgen und die Spezifikationen zu lesen, die dir nahegelegt werden.
Ich denke eher daß sich die Entwickler von xhr und Browser mal damit befassen sollten um hier ein einheitliches Verhalten vorzulegen. Den Default Enctype gibt es ja nicht umsonst und dieser macht ja auch Sinn, zumal Browser ohnehin nur 2 Enctypes unterstützen. Somit ändert xhr den Default eigenmächtig auf text/plain und das weicht vom korrekten Verhalten des Browsers ab.
Aber letztendlich ist das alles nicht mein Problem. MFG
Den Default Enctype gibt es ja nicht umsonst und dieser macht ja auch Sinn, zumal Browser ohnehin nur 2 Enctypes unterstützen.
Im Sinne stukturierter Daten!
Hallo Email,
XHR bzw. fetch haben keinen Default-enctype. Den haben nur Forms.
Damit fehlt Dir deine Vergleichsgrundlage. XHR ist kein Form. Es kann auch Formdaten senden, aber dann bitte so, wie die Spec es vorsieht. Machst Du was anderes, passiert auch was anderes. Exakt nach Spec.
Du müsstest dir einfach mal die Mühe machen, den Links zu folgen und die Spezifikationen zu lesen, die dir nahegelegt werden.
Ich denke eher daß ...
Das ist dein Problem. Du hast eine Vorstellung vom Sachverhalt und setzt sie für Dich als einzig richtig. Aber leider haben sich andere Leute andere Gedanken gemacht und sie in einem Konsensprozess, an dem Du und ich nicht beteiligt waren, zur Norm erhoben. Damit müssen wir uns leider abfinden. Wir können lange über hätte und könnte und mimimi-ichwillaber reden, das ändert trotzdem nichts an der Spec. Lies sie, nutze sie, und du kommst voran. Oder verschaffe Dir weltweit soviel Reputation, dass Du zur Mitarbeit an der Spec eingeladen wirst. Good Luck!
Rolf
XHR bzw. fetch haben keinen Default-enctype. Den haben nur Forms.
Der Enctype bzw. Content-Type application/x-www-form-urlencoded
ist der Default für den serverseitigen Parser, auch der in PHP verbaute Parser nimmt diesen Default an wenn kein Content-Type gesendet wurde. Das hat nichts Forms zu tun sondern mit CGI/1.1.
Und ja natürlich entwickelt jeder sein eigenes Verständnis, wäre ja schlimm wenn das nicht so wäre.
MFG
Hallo Email,
RFC3875 (CGI), Abschnitt 4.1.3 (CONTENT_TYPE) widerspricht dem klar und deutlich.
Auf welche Spec stützt du deine Behauptung?
Rolf
RFC3875 (CGI), Abschnitt 4.1.3 (CONTENT_TYPE) widerspricht dem klar und deutlich.
Ich sehe da keinen Widerspruch. Die in 4.1.3 getroffene Aussage
There is no default value for this variable.
bezieht sich auf die zu setzende Umgebungsvariable CONTENT_TYPE
.
Und genau das heißt für den Parser, daß er einen bestimmten Enctype annehmen muss wenn diese Variable nicht gesetzt ist.
Hast Du schonmal selbst einen Parser entwickelt? Was wäre denn Deine Entscheidung wenn kein CONTENT_TYPE
gegeben ist, welchen Enctype würdest Du für den QUERY_STRING
annehmen?
8.2 hierzu:
If CONTENT_TYPE is blank, the script can reject the request with a 415 'Unsupported Media Type' error, where supported by theprotocol.
Also eine Kannbestimmung.
MFG
Hallo Email,
Lies alles!
There is no default value for this variable. If and only if it is unset, then the script MAY attempt to determine the media type from the data received. If the type remains unknown, then the script MAY choose to assume a type of application/octet-stream or it may reject the request with an error (as described in section 6.3.3).
Fett von mir.
Der Parser ist Teil des Scripts. Wenn CONTENT_TYPE nicht gesetzt ist, DARF das Script an den Daten schnuppern und versuchen, einen enctype zu erraten. Gelingt das nicht oder will es das nicht, DARF das Script die Daten als octet-stream interpretieren oder den Request abweisen.
Da steht ausdrücklich nicht, dass es im Zweifelsfall ungeprüft auf urlencoded zurückfallen soll.
Wenn XHR bei send("x=y&z=3") automatisch text/plain als Content-Type setzt, werden diese beiden MAY ausgehebelt, das ist richtig. XHR ist aber einen Level tiefer als ein Form. Willst Du einen String mit einem bestimmten MIME Typ senden, musst Du das setzen. Andernfalls ist's halt einfach nur ein text/plain String.
Rolf
There is no default value for this variable. If and only if it is unset, then the script MAY attempt to determine the media type from the data received. If the type remains unknown, then the script MAY choose to assume a type of application/octet-stream or it may reject the request with an error (as described in section 6.3.3).
Fett von mir.
Der Parser ist Teil des Scripts. Wenn CONTENT_TYPE nicht gesetzt ist, DARF das Script an den Daten schnuppern und versuchen, einen enctype zu erraten. Gelingt das nicht oder will es das nicht, DARF das Script die Daten als octet-stream interpretieren oder den Request abweisen.
Nun, ich kenne keinen Parser der sich so verhält. Wie sich PHP verhält hab ich schon geschrieben. Das CGI.pm von Perl nimmt für den Fall daß kein CONTENT_TYPE vorliegt den Default Enctype an, egal ob die Daten aus dem QUERY_STRING oder aus STDIN gelesen werden.
Der Default ist application/x-www-form-urlencoded
.
Die Parser die ich programmiert habe entscheiden im Gegensatz zu CGI.pm anhand CONTENT_LENGTH wo die zu parsenden Daten zu finden sind, also entweder in STDIN oder im QUERY_STRING unabhängig von der Requestmethode.
Insgesamt ist die Frage der Logik eine praktische Frage und da macht der Default application/x-www-form-urlencoded
schon einen Sinn. Keinen Sinn hingegen macht es für einen Parser einen Default application/octet-stream
anzunehmen, weil es praktisch keinen Browser gibt welcher diesen Enctype sendet und dieser Enctype von vornherein ausschließt daß strukturierte Daten vorligen. Ungemein praktisch ist es, den Parser als eine eigenständige Klasse anzulegen und diesen erweiterbar zu machen für beliebige Content-Types. CGI/1.1 umfasst ja nicht nur STDIN und den QUERY_STRING, auch Customheader sind Parameter die zum Request gehören.
MFG
Wir sollten hier mal ein paar Begriffe klären, die du konsequent falsch benutzt.
Ein Parser ist ein Programm, das einen Eingabestrom in eine abstrakte Repräsentation übersetzt. Der Eingabestrom ist oft eine Zeichenkette, die Ausgabe typischerweise ein abstrakter Syntaxbaum. Ein Parser erwartet immer, dass die Eingabe einem bestimmten Format folgt. Nur wenn die Eingabe wirklich dieses Format hat, kann der Parser daraus eine abstrake Repräsentation erzeugen. Falls nicht, dann bricht ein Parser ab und meldet einen Syntax-Fehler. Es macht keinen Sinn einem JSON-Parser einen CSV-String zu geben oder umgekehrt. Genausowenig macht es Sinn einem Parser für multipart/form-data
einen Eingabestrom im application/x-www-form-urlencoded
Format zu geben. All diese Fälle sollten Syntax-Fehler produzieren.
CGI ist eine Spezifikation, die eine Laufzeit-Umgebung für Webserver standardisiert. Darin wird zum Beispiel festgelegt, dass die Querystring-Komponente der angefragten URL in einer Umgebungsvariable namens QUERYSTRING
gespeichert werden soll. Da wird aber nicht festgelegt, welches Format die Querystring-Komponente hat, und auch nicht ob sie geparst werden soll. Weiterhin steht in CGI, dass der HTTP-Body über eine nicht-weiter spezifizierte Systemfunktion gelesen werden können muss. CGI schreibt ausdrücklich nicht vor, ob und in welchem Format der Body geparst werden soll.
CGI.pm und mod_cgi sind Implementierungen dieses Standards. Ein Skript, das in diesem Kontext ausgeführt wird, hat Zugriff auf die Umgebungsvariablen, die CGI festlegt und sie haben irgendeine Möglichkeit den HTTP-Body zu lesen. Das kann, muss aber nicht der STDIN-Kanal sein. Eine Implementierung kann darüber hinaus auch eigene Design-Entscheidungen treffen. Wenn eine HTTP-Anfrage eintrifft, kann eine Implementierung auch den Body und den Content-Type-Header auswerten und dann intern einen Parser für den Content-Type wählen und versuchen den Body in eine abstrakte Repräsentation zu übersetzen. Oder die Implementierung kann einfach ins Blaue versuchen den Body mit verschiedenen Parsern zu dekodieren. Das ist aber alles Zusatzverhalten, das nicht von CGI so spezifiziert wurde. Es ist eine Frage der konkreten Implementierung, nicht von CGI, wie du vorher behauptet hast.
Neben CGI gibt es außerdem noch andere Standards, die ebenfalls Laufzeitumgebungen für Webserver spezifizieren, wie FastCGI. Und es gibt Laufzeitumgebungen, die keiner Spezifikation folgen, wie mod_php. CGI ist heute mehrfach überholt und kommt nur noch selten zum Einsatz, insbesondere im PHP-Kosmos spielt CGI keine große Rolle mehr.
Nur als Hinweis zu CGI/1.1: STDIN und STDOUT sind der eigentliche Common Gateway aus dem sich die Abkürzung CGI ableitet.
Der Standard selbst wurde nur geschaffen um 1. Entwicklern eine einheitliche API in die Hand zu legen und 2. ein sog. Low-Level-Parsing vorzunehmen, was sämtliche zum Request gehörige Parameter in die Serverumgebung setzt und den Messagebody für nachgelagerte Prozesse bereitstellt die einen Solchen aus STDIN lesen können.
So nimmt ein c-Programmierer einfach die Funktion getenv("CONTENT_TYPE")
wohingegen ein Perl-Programmierer in den Hash $ENV{CONTENT_TYPE}
greift um den entsprechenden Wert abzufragen.
MFG
Nur als Hinweis zu CGI/1.1: STDIN und STDOUT sind der eigentliche Common Gateway aus dem sich die Abkürzung CGI ableitet.
Bullshit.
Der Standard selbst wurde nur geschaffen um 1. Entwicklern eine einheitliche API in die Hand zu legen und
Ja, das haben Standards so an sich.
- ein sog. Low-Level-Parsing vorzunehmen
Bullshit.
Lies den Standard.
Ergänzung: CGI/1.1 legt also nur fest, wie ein Webserver einen HTTP Request aufzuarbeiten hat. Und so macht ein Webserver nichts weiter als dies:
Aufgrund des Layers auf dem CGI/1.1 angesiedelt ist und seiner Einfachheit, wird CGI/1.1 auch als Low-Level-Schnittstelle bezeichnet. Das weitere Parsen eines Request anhand des gesendetetn CONTENT_TYPE
ist Sache des Anwendungslayers. Der Webserver selbst also kennt keinen CONTENT_TYPE.
Mod_php, mod_perl, FastCGI u.a. Plugins ändern nichts am oben dargestellten Sachverhalt.
Anmerkung: In RFC3857 werden STDIN als standard input
(4.2) und STDOUT als standard output
(6.1) benannt.
Es kommt auch gar nicht auf einzlne Begriffe an sondern darum, den Zusammenhang zu verstehen. Jeder heutige Programmierer denkt in Layers und solche Modelle sind schon außerordentlich sinnvoll. Wesentlich also ist, daß das weitere Parsen eines Request den CGI/1.1 für den nachgelagerten Prozess aufgearbeitet hat eine Sache der Anwendung ist. So ist, wie @Rolf B schon schrieb, der Parser ein Teil des Scripts (also der Anwendung).
Parser in Perl wie z.B. CGI.pm
gehen noch einen Schritt weiter in Richtung einer eigenständigen Klasse (OOP). Die Logik die in CGI.pm verbaut ist, basiert auf einem Default-Content-Type und das hat sich jahrzehntelang bewährt!
Mit freundlichen Grüßen!
Hallo,
Anmerkung: In RFC3857 werden STDIN als
standard input
(4.2) und STDOUT alsstandard output
(6.1) benannt.
Hattest du das bisher immer umgekehrt verstanden?
Gruß
Kalk
Nur als Hinweis zu CGI/1.1: STDIN und STDOUT sind der eigentliche Common Gateway aus dem sich die Abkürzung CGI ableitet.
Interessanter Artkel hierzu: CGI/1.1 zu CGI/1.2
Issue: In CGI/1.1 wird der gesamte Bytestream eines Request vom Webserver gepuffert bevor dieser auf dem Bytelevel geparst und der gesamte Body in den Puffer von STDOUT geschrieben wird (das macht der Webserver).
D.h., daß ein echtes Streaming in v1.1 nicht möglich ist. Dem soll mit CGI/1.2 abgehholfen werden.
Der Artikel, Link s.o., ist von 1999. Wir dürfen heute, 20 Jahre später also, gespannt sein wie die Entwicklung weitergehen wird 😉
MFG
Der Artikel, Link s.o., ist von 1999. Wir dürfen heute, 20 Jahre später also, gespannt sein wie die Entwicklung weitergehen wird
Wobei es jedem Entwickler klar sein dürfte daß ein CGI/1.2 nur mit einer Weiterentwicklung von HTTP möglich ist. Der Autor des Artikels, Lincoln D. Stein kommt von Perl. Bemerkenswert, wie richtungsweisend seine damaligen Gedankengänge sind. Und bemerkenswert, daß seither 15 Jahre vergehen mussten bis ein HTTP/2.0 in der einschlägigen IT-Presse überhaupt erwähnt wurde, also im Jahr 2014.
MFG
Noch ein Tipp falls Du mal vorhast einen Parser zu entwickeln:
Ob Daten aus STDIN, Customheaders oder Query_String zu parsen sind, entscheiden nicht nur die REQUEST_METHOD und CONTENT_LENGTH. In Hinblick auf mögliche Erweiterungen bezüglich neuer Content-Types und auch Custom-Content-Types kann das nämlich auch letzterer entscheiden.
Abstrakt: Der gesendete Content-Type ist eine Vorschrift dafür wie der gesamte Request zu verarbeiten ist!
Bspw. legt mein Content-Type application/body+query
fest, daß der QUERY_STRING strukturierte Daten als Enctype application/x-www-form-urlencoded
enthält die ganz herkömmlich zu parsen sind. Diese Daten ergeben bspw. die Parameter für eine (Achtung Fremdwort:) Parameterkontrollstruktur (Schlüsselparameter).
Zusätzlich gehört aber auch der Body zum Request und der kann dann beliebige Content-Types beeinhalten, von reinen Binaries bis XML und JSON.
Und das ist wirklich mal was Neues im Vergleich zu den verstaubten Requisiten die MDN nur neu verpackt!
Bleiben Sie kreativ.
Noch ein Tipp falls Du mal vorhast einen Parser zu entwickeln:
Und betrachte den Content-Type als austauschbaren Layer! D.h., daß man am Client die Wahl hat zwischen verschiedenen Enctypes und daß dabei serverseitig nicht eine Zeile Code zu ändern ist.
So sind die Enctypes application/x-www-form-urlencoded
und multipart/form-data
die Klassiker was Kompatibilität betrifft, von der Möglichkeit des FileUplaod einmal abgesehen. Aber diese Beiden sind ja nicht die ganze Welt.
Bspw. beschreibt ein Enctype application/json
allenfalls ein Verfahren zur Serialisierung/Wiederherstellung aber ein Enctype application/soap+json
beschreibt auch die Schlüsselfelder.
Deiner Kreativität sind keine Grenzen gesetzt ;)
XHR bzw. fetch haben keinen Default-enctype. Den haben nur Forms.
Der Enctype bzw. Content-Type
application/x-www-form-urlencoded
ist der Default für den serverseitigen Parser, auch der in PHP verbaute Parser nimmt diesen Default an wenn kein Content-Type gesendet wurde. Das hat nichts Forms zu tun sondern mit CGI/1.1.
Besser gesagt: Mit der dem Webserver über CGI angebundenen Anwendung. Insofern ist es mir völlig unverständlich daß XHR einen Content-Type text/plain
bzw. application/octet-stream
(siehe Spec.) generiert.
Und ja natürlich entwickelt jeder sein eigenes Verständnis, wäre ja schlimm wenn das nicht so wäre.
Schlüssig wäre, daß XHR, wenn infolge der Überlagerung der send()-Funktion weder application/x-www-form-urlencoded
noch multipart/form-data
erkannt wurden, gar keinen Content-Type-Header sendet.
So sehe ich das, danke fürs Mitlesen.
Schlüssig wäre, daß XHR, wenn infolge der Überlagerung der send()-Funktion weder
application/x-www-form-urlencoded
nochmultipart/form-data
erkannt wurden, gar keinen Content-Type-Header sendet.
Da Du ja so überzeugt bist, hier ein paar Hinweise für Dich:
https://github.com/mozilla/gecko-dev
https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Introduction
Viel Spaß!
Schlüssig wäre, daß XHR, wenn infolge der Überlagerung der send()-Funktion weder
application/x-www-form-urlencoded
nochmultipart/form-data
erkannt wurden, gar keinen Content-Type-Header sendet.Da Du ja so überzeugt bist, hier ein paar Hinweise für Dich:
Was ich brauche ist eine praktische Lösung. Und mittlerweile habe ich eine die zwar die Ursachen nicht beseitigt aber die Symptome dieser Krebsgeschwüre einigermaßen erträglich macht 😉
MFG
Was ich brauche ist eine praktische Lösung. Und mittlerweile habe ich eine die zwar die Ursachen nicht beseitigt aber die Symptome dieser Krebsgeschwüre einigermaßen erträglich macht 😉
Was spricht denn gegen den Vorschlag von Rolf aus seiner aller ersten Antwort in diesem Thread? Der löst das Problem an der Wurzel und bekämpft nicht nur Symptome und ist ungemein praktisch.
Hallo 1unitedpower,
Was spricht denn gegen den Vorschlag von Rolf aus seiner aller ersten Antwort in diesem Thread?
Nichts, außer der Tatsache, dass Hotti keine Lösung sucht, sondern einen Anlass für ausschweifende Vorträge. Ich mach das hier jetzt zu.
Rolf
Und schon gar nicht den Enctype selbst erraten.
Es wird nichts geraten, das Verhalten ist so spezifiziert.
xhr errät aus
x=y
den Content-Typetext/plain; charset=UTF-8
und sendet diesen Header spontan im Request.
Es wird nichts geraten, das Verhalten ist so spezifiziert.
Ein HTML <form method="POST">, also ohne Angabe des Enctype sendet den Default Content-Type mit demselben Payload
x=y
.
Wenn ein Formular kein enctype-Attribut hat, wird beim Senden des Formulars implizit application/x-www-form-urlencoded
als Kodierung gewählt.
Wenn man XMLHttpRequest.prototype.send
mit einem URLSearchParams
-Objekt aufruft, dann wird implizit application/x-www-form-urlencoded
als Kodierung gewählt.
Wenn man XMLHttpRequest.prototype.send
mit einem USVString
aufruft, dann wird implizit text/plain
als Kodierung gewählt.
Die send
-Methode ist überladen. Je nach Typ des Parameters wird eine passende Kodierung gewählt. Welche Kodierung gewählt wird, musst du nicht raten, du kannst es in der Spezifikation nachlesen. Spätestens nachdem du das zweite Mal damit auf die Nase gefallen bist, solltest du das mal in Erwägung ziehen.
Man könnte also durchaus erwarten, daß sich xhr genauso wie ein Browser verhält, was jedoch definitiv nicht der Fall ist. Siehe Spezifikation (Link weiter oben).
Man könnte auch einfach mal 10 Minuten Handbuch lesen, anstatt ewig im Dunklen zu stochern.
Du müsstest dir einfach mal die Mühe machen, den Links zu folgen und die Spezifikationen zu lesen, die dir nahegelegt werden.
Ich denke eher daß sich die Entwickler von xhr und Browser mal damit befassen sollten um hier ein einheitliches Verhalten vorzulegen.
Erstens, lies die Spezifikation bevor du sie kritisierst. Zweitens, kritisier die Spezifikation inhaltlich, nicht ihre Autor*innen.
Die neuen Standards und Begriffe sind ja nichts Neues sondern auch nur eine neue Verpackung für den ganzen alten Schrott.
Zweitens, kritisier die Spezifikation inhaltlich, nicht ihre Autor*innen.
Daß FormData Schrott ist, kritisiere ich schon seit Jahrzehnten! Begründung und welcher schwerwiegende Designfehler drinsteckt auf meiner Website. MFG