378 Stimmen

Was bedeutet "Content-type: application/json; charset=utf-8" wirklich?

Wenn ich eine POST-Anforderung mit einem JSON-Body an meinen REST-Dienst stelle, schließe ich ein Content-type: application/json; charset=utf-8 in der Kopfzeile der Nachricht. Ohne diese Kopfzeile bekomme ich eine Fehlermeldung vom Dienst. Ich kann auch erfolgreich verwenden Content-type: application/json ohne die ;charset=utf-8 Teil.

Was genau bedeutet charset=utf-8 tun? Ich weiß, dass er die Zeichenkodierung angibt, aber der Dienst funktioniert auch ohne diese. Begrenzt diese Kodierung die Zeichen, die im Nachrichtentext enthalten sein können?

365voto

deceze Punkte 489288

Die Kopfzeile gibt lediglich an, in welcher Sprache der Inhalt kodiert ist. Es ist nicht unbedingt möglich, aus dem Inhalt selbst auf die Art des Inhalts zu schließen, d. h. man kann nicht einfach auf den Inhalt schauen und wissen, was man mit ihm machen soll. Dafür sind die HTTP-Header da, die dem Empfänger mitteilen, mit welcher Art von Inhalt er es (vermeintlich) zu tun hat.

Content-type: application/json; charset=utf-8 bezeichnet den Inhalt im JSON-Format, kodiert in der Zeichenkodierung UTF-8. Die Angabe der Kodierung ist für JSON etwas überflüssig, da die Standardkodierung (die einzige?) für JSON UTF-8 ist. In diesem Fall ist der empfangende Server offenbar froh, dass er weiß, dass er es mit JSON zu tun hat, und geht davon aus, dass die Kodierung standardmäßig UTF-8 ist, weshalb er mit oder ohne Header funktioniert.

Begrenzt diese Kodierung die Zeichen, die im Nachrichtentext enthalten sein können?

Nein. Sie können in der Kopfzeile und im Textkörper alles senden, was Sie wollen. Aber wenn die beiden nicht übereinstimmen, können Sie falsche Ergebnisse erhalten. Wenn Sie im Header angeben, dass der Inhalt UTF-8 kodiert ist, Sie aber eigentlich Latin1 kodierte Inhalte senden, kann der Empfänger Datenmüll produzieren, weil er versucht, Latin1 kodierte Daten als UTF-8 zu interpretieren. Wenn Sie natürlich angeben, dass Sie Latin1-kodierte Daten senden und dies auch tatsächlich tun, dann sind Sie auf die 256 Zeichen beschränkt, die Sie in Latin1 kodieren können.

164voto

Drew Noakes Punkte 282438

Um die Behauptung von @deceze zu bestätigen, dass die Standard-JSON-Kodierung UTF-8 ist...

En IETF RFC4627 :

JSON-Text MUSS in Unicode kodiert sein. Die Standardkodierung ist UTF-8.

Da die ersten beiden Zeichen eines JSON-Textes Zeichen sind [RFC0020], ist es möglich zu bestimmen, ob ein Oktett Stream UTF-8, UTF-16 (BE oder LE), oder UTF-32 (BE oder LE) ist, indem man auf das Muster der Nullen in den ersten vier Oktetten.

      00 00 00 xx  UTF-32BE
      00 xx 00 xx  UTF-16BE
      xx 00 00 00  UTF-32LE
      xx 00 xx 00  UTF-16LE
      xx xx xx xx  UTF-8

24voto

Alex Punkte 241

Beachten Sie, dass IETF RFC4627 wurde abgelöst durch IETF RFC7158 . In Abschnitt [8.1] wird der von @Drew zitierte Text zurückgenommen, indem es heißt:

Implementations MUST NOT add a byte order mark to the beginning of a JSON text.

6voto

starriet Punkte 990

RFC 8259 :

  1. IANA-Überlegungen

Der Medientyp für JSON-Text ist application/json.
...
注意してください。 Für diese Registrierung ist kein "charset"-Parameter definiert. Die Hinzufügung eines solchen Elements hat keine Auswirkungen auf konforme Empfänger.

Auch,

8.1. Zeichenkodierung

JSON-Text, der zwischen Systemen ausgetauscht wird, die nicht Teil eines geschlossenen Systems sind
Ökosystem MUSS mit UTF-8 [RFC3629] kodiert werden.

Frühere JSON-Spezifikationen haben die Verwendung von UTF-8 nicht verlangt. bei der Übertragung von JSON-Text. Allerdings ist die große Mehrheit der JSON-
basierte Softwareimplementierungen haben sich für die UTF-8-Kodierung entschieden, da dies die einzige Kodierung ist, die die folgenden Anforderungen erfüllt
Interoperabilität.

Implementierungen MÜSSEN NICHT eine Byte Order Mark (U+FEFF) zum
Beginn eines über das Netzwerk übertragenen JSON-Textes. Im Interesse der
Interoperabilität, können Implementierungen, die JSON-Texte parsen, ignorieren
das Vorhandensein einer Byte-Order-Marke, anstatt sie als
Fehler.

(Hervorhebung von mir)

1voto

roipeker Punkte 1115

Dart http-Implementierung verarbeiten die Bytes dank dieser "charset=utf-8", so bin ich sicher, dass mehrere Implementierungen da draußen unterstützt dies, um die "latin-1" Fallback-Charset beim Lesen der Bytes aus der Antwort zu vermeiden. In meinem Fall verliere ich das Format des Antwortkörpers völlig, so dass ich die Bytes manuell in utf8 kodieren muss, oder den Header-Parameter "inner" in der API-Antwort meines Servers hinzufügen muss.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X