Что означает "Content-type: application/json; charset = utf-8"?

Когда я отправляю запрос POST с телом JSON в службу REST, я включаю Content-type: application/json; charset=utf-8 в заголовок сообщения. Без этого заголовка я получаю сообщение об ошибке из службы. Я также могу успешно использовать Content-type: application/json без части ;charset=utf-8.

Что именно делает charset=utf-8? Я знаю, что он задает кодировку символов, но сервис отлично работает без него. Ограничивает ли эта кодировка символы, которые могут находиться в теле сообщения?

Ответ 1

Заголовок просто обозначает, в чем кодируется содержимое. Не обязательно выводить тип содержимого из самого содержимого, т.е. вы не можете просто просто посмотреть контент и знать, что с ним делать. Для того, для чего предназначены HTTP-заголовки, они сообщают получателю, какой контент они (предположительно) имеют дело с.

Content-type: application/json; charset=utf-8 обозначает содержимое, которое должно быть в формате JSON, закодированное в кодировке символов UTF-8. Назначение кодировки несколько избыточно для JSON, поскольку кодировка по умолчанию (только?) Для JSON - это UTF-8. Таким образом, в этом случае получающий сервер, по-видимому, счастлив, зная, что он имеет дело с JSON и предполагает, что кодировка UTF-8 по умолчанию, почему он работает с заголовком или без него.

Ограничивает ли эта кодировка символы, которые могут находиться в теле сообщения?

Нет. Вы можете отправить все, что хотите, в заголовок и тело. Но, если они не совпадают, вы можете получить неправильные результаты. Если вы укажете в заголовке, что содержимое кодировано в кодировке UTF-8, но вы фактически отправляете контент с кодировкой Latin1, получатель может создавать данные об мусоре, пытаясь интерпретировать данные с кодировкой Latin1 как UTF-8. Если, конечно, вы укажете, что вы отправляете кодированные данные Latin1, и вы на самом деле делаете это, тогда да, вы ограничены 256 символами, которые вы можете кодировать в Latin1.

Ответ 2

Чтобы обосновать @deceze, утверждается, что кодировка JSON по умолчанию - UTF-8...

Из IETF RFC4627:

Текст JSON будет закодирован в Юникоде. Кодировка по умолчанию   UTF-8.

Поскольку первые два символа текста JSON всегда будут ASCII   символов [RFC0020], можно определить, является ли октет   поток UTF-8, UTF-16 (BE или LE) или UTF-32 (BE или LE) путем поиска   при шаблоне нулей в первых четырех октетах.

      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

Ответ 3

Обратите внимание, что IETF RFC4627 был заменен IETF RFC7158. В разделе [8.1] он убирает текст, цитируемый ранее @Drew, говоря:

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

Ответ 4

Я полностью согласен с @deceze, но я хочу развить эту часть вопроса "Я получаю ошибку от службы",

Мы получаем такие ошибки как http 415

Http 415 Неподдерживаемая ошибка типа носителя

Код ответа об ошибке клиента HTTP 415 Unsupported Media Type указывает, что сервер отказывается принять запрос, потому что формат полезной нагрузки находится в неподдерживаемом формате.

Проблема с форматированием может быть связана с указанным запросом Content-Type или Content-Encoding, либо из-за прямой проверки данных.

Другими словами, как показано в fooobar.com/questions/108775/... этом примере.

  • Мы должны установить правильный тип содержимого, и мы должны принять правильный тип содержимого, как показано. Добавить Content-Type: application/json и Accept: application/json. В противном случае он примет значение по умолчанию

Ответ 5

Реализация http в Dart обрабатывает байты благодаря этому "charset = utf-8", поэтому я уверен, что некоторые реализации поддерживают это, чтобы избежать "латинского-1" запасного набора символов при чтении байтов из ответа. В моем случае я полностью теряю формат в строке тела ответа, поэтому мне приходится вручную кодировать байты в utf8 или добавлять этот параметр "внутренний" заголовка в мой ответ API сервера.