Wenn ich eine POST-Anfrage mit einem JSON-Body an meinen REST-Service stelle, füge ich sie Content-type: application/json; charset=utf-8
in den Nachrichtenkopf ein. Ohne diesen Header erhalte ich eine Fehlermeldung vom Dienst. Ich kann auch erfolgreich Content-type: application/json
ohne die ;charset=utf-8
Portion verwenden.
Was genau macht charset=utf-8
das? Ich weiß, dass es die Zeichenkodierung angibt, aber der Dienst funktioniert ohne sie einwandfrei. Beschränkt diese Codierung die Zeichen, die sich im Nachrichtentext befinden können?
character-encoding
mime-types
DenaliHardtail
quelle
quelle
application/json
Medientyp Registrierung , wird es nicht angezeigt , ein unterstützt werdencharset
Parameter überhaupt, wenn auch in der Praxis häufig zugeführt wird.I know it specifies the character encoding but the service works fine without it.
"Arbeiten" bedeutet nicht immer "Der vorhandene Code / die vorhandene Konfiguration ist der korrekteste Weg, um alle Eckfälle abzudecken und eine Sache zu tun". Dies hängt von allen Konventionen und Annahmen ab, die unter anderen Umständen möglicherweise nicht funktionieren. Für mich persönlich versuche ich immer, so explizit wie möglich zu sein.Antworten:
Der Header gibt nur an, in was der Inhalt codiert ist. Es ist nicht unbedingt möglich, den Typ des Inhalts aus dem Inhalt selbst abzuleiten, dh Sie können nicht unbedingt nur den Inhalt betrachten und wissen, was damit zu tun ist. Dafür sind HTTP-Header gedacht. Sie teilen dem Empfänger mit, um welche Art von Inhalten es sich (angeblich) handelt.
Content-type: application/json; charset=utf-8
bezeichnet den Inhalt im JSON-Format, das in der UTF-8-Zeichencodierung codiert ist. Das Festlegen der Codierung ist für JSON etwas redundant, da die Standardcodierung (nur?) Für JSON UTF-8 ist. In diesem Fall ist der empfangende Server anscheinend froh zu wissen, dass es sich um JSON handelt, und geht davon aus, dass die Codierung standardmäßig UTF-8 ist. Deshalb funktioniert er mit oder ohne Header.Nein. Sie können im Header und im Body alles senden, was Sie wollen. Wenn die beiden jedoch nicht übereinstimmen, erhalten Sie möglicherweise falsche Ergebnisse. Wenn Sie im Header angeben, dass der Inhalt UTF-8-codiert ist, Sie jedoch tatsächlich Latin1-codierten Inhalt senden, erzeugt der Empfänger möglicherweise Mülldaten und versucht, Latin1-codierte Daten als UTF-8 zu interpretieren. Wenn Sie natürlich angeben, dass Sie Latin1-codierte Daten senden und dies tatsächlich tun, sind Sie auf die 256 Zeichen beschränkt, die Sie in Latin1 codieren können.
quelle
\u20AC
.application/json
muss in einem der UCS-Transformationsformate sein. Da die ersten vier Bytes von JSON begrenzt sind, können Sie immer erkennen, ob es sich um 8, 16 oder 32 handelt, und um die Endianität.charset=utf-8
aus Sicherheitsgründen einschließen : github.com/shieldfy/API-Security-Checklist/issues/25Um die Behauptung von @ deceze zu untermauern, dass die Standard-JSON-Codierung UTF-8 ist ...
Von IETF RFC4627 :
quelle
"\u0000"
).xx 00 00 00
ist immer noch UTF-32LE undxx 00 xx xx
ist immer noch UTF-16LE,00 xx xx xx
ist immer noch UTF-16BE.Beachten Sie, dass IETF RFC4627 durch IETF RFC7158 ersetzt wurde . In Abschnitt [8.1] wird der zuvor von @Drew zitierte Text zurückgezogen, indem gesagt wird:
quelle
Ich stimme @deceze genau zu, aber ich möchte diesen Teil der Frage "Ich erhalte einen Fehler vom Dienst" entwickeln.
Wir bekommen diese Art von Fehlern als http 415
Der HTTP 415-Client-Fehlerantwortcode für nicht unterstützte Medientypen gibt an, dass der Server die Anforderung nicht akzeptiert, da das Nutzdatenformat in einem nicht unterstützten Format vorliegt.
Das Formatproblem kann auf den angegebenen Inhaltstyp oder die Inhaltscodierung der Anforderung oder auf die direkte Überprüfung der Daten zurückzuführen sein.
Mit anderen Worten, wie in https://stackoverflow.com/a/22643964/914284 dieses Beispiel zu sehen.
quelle
Die Implementierung von Dart http verarbeitet die Bytes dank dieses "charset = utf-8". Ich bin sicher, dass mehrere Implementierungen dies unterstützen, um den Fallback-Zeichensatz "latin-1" beim Lesen der Bytes aus der Antwort zu vermeiden. In meinem Fall verliere ich das Format der Antworttextzeichenfolge vollständig, daher muss ich die Bytecodierung manuell in utf8 durchführen oder diesen "inneren" Headerparameter zur API-Antwort meines Servers hinzufügen.
quelle
Ich habe HttpClient verwendet und den Antwortheader mit dem Inhaltstyp zurückgegeben
application/json
. Ich habe Zeichen wie Fremdsprachen oder Symbole verloren, die Unicode verwendeten, da HttpClient standardmäßig ISO-8859-1 ist . Seien Sie also so explizit wie möglich, wie von @WesternGun erwähnt, um mögliche Probleme zu vermeiden.Es gibt keine Möglichkeit, dass der Server den angeforderten Header-Zeichensatz (
method.setRequestHeader("accept-charset", "UTF-8");
) für mich nicht verarbeitet , und ich musste Antwortdaten als Zeichenbytes abrufen und sie mit UTF-8 in einen String konvertieren. Es wird daher empfohlen, explizit zu sein und die Annahme eines Standardwerts zu vermeiden.quelle