Кодировка символов JSON - хорошо ли поддерживается браузерами UTF-8 или мне следует использовать числовые escape-последовательности? - PullRequest
77 голосов
/ 24 февраля 2009

Я пишу веб-сервис, который использует json для представления своих ресурсов, и я немного застрял, размышляя о лучшем способе кодирования json. Чтение json rfc (http://www.ietf.org/rfc/rfc4627.txt) ясно, что предпочтительной кодировкой является utf-8. Но rfc также описывает механизм экранирования строк для указания символов. Я предполагаю, что это обычно используется для экранирования не-ascii символов тем самым делая полученный utf-8 действительным ascii.

Итак, допустим, у меня есть строка json, которая содержит символы Unicode (кодовые точки), которые не являются ascii. Должен ли мой веб-сервис просто кодировать это utf-8 и вернуть его, или он должен экранировать все эти символы, не являющиеся ascii, и вернуть чистый ascii?

Я бы хотел, чтобы браузеры могли выполнять результаты, используя jsonp или eval. Это влияет на решение? Мои знания о поддержке различных браузеров javascript для utf-8 отсутствуют.

РЕДАКТИРОВАТЬ: я хотел уточнить, что моя главная забота о том, как кодировать результаты на самом деле о обработке результатов в браузере. То, что я прочитал, указывает на то, что браузеры могут быть чувствительны к кодировке, в частности, при использовании JSONP. Я не нашел по-настоящему хорошей информации по этому вопросу, поэтому мне придется начать тестирование, чтобы увидеть, что произойдет. В идеале я хотел бы избежать только тех немногих символов, которые требуются, и просто utf-8 кодирует результаты.

Ответы [ 6 ]

75 голосов
/ 27 февраля 2009

Спецификация JSON требует поддержки UTF-8 декодерами. В результате все JSON-декодеры могут обрабатывать UTF-8 так же хорошо, как они могут обрабатывать числовые escape-последовательности. Это также относится и к интерпретаторам Javascript, что означает, что JSONP также будет обрабатывать кодированный в UTF-8 JSON.

Возможность кодировщикам JSON использовать числовые escape-последовательности вместо этого просто предлагает вам больший выбор. Одна из причин, по которой вы можете выбрать числовые escape-последовательности, заключается в том, что транспортный механизм между вашего кодировщика и предполагаемым декодером не является бинарно-безопасным.

Другая причина, по которой вы можете захотеть использовать числовые escape-последовательности, состоит в том, чтобы предотвратить появление в потоке определенных символов, таких как <, & и ", которые могут интерпретироваться как последовательности HTML, если размещен код JSON без перехода в HTML или браузер неправильно интерпретирует его как HTML. Это может быть защита от внедрения HTML или межсайтового скриптинга (примечание: некоторые символы ДОЛЖНЫ быть экранированы в JSON, включая " и \).

Некоторые фреймворки, включая реализацию PHP JSON, всегда выполняют числовые escape-последовательности на стороне кодировщика для любого символа вне ASCII. Это предназначено для максимальной совместимости с ограниченными транспортными механизмами и тому подобным. Однако это не следует интерпретировать как указание на то, что у JSON-декодеров есть проблема с UTF-8.

Итак, я думаю, вы просто могли решить, что использовать следующим образом:

  • Просто используйте UTF-8, если только ваш метод хранения или передачи между кодером и декодером не является бинарно-безопасным.

  • В противном случае используйте числовые escape-последовательности.

15 голосов
/ 12 августа 2009

У меня была проблема там. Когда я JSON кодирую строку с таким символом, как «é», все браузеры возвращают одно и то же «é», кроме IE, который возвращает «\ u00e9».

Затем с помощью PHP json_decode () произойдет сбой, если он найдет «é», поэтому для Firefox, Opera, Safari и Chrome я должен вызвать utf8_encode () перед json_decode ().

Примечание: в моих тестах IE и Firefox используют свой собственный объект JSON, другие браузеры используют json2.js.

12 голосов
/ 25 февраля 2009

ASCII больше не существует. Использование кодировки UTF-8 означает, что вы не используете кодировку ASCII. Для чего вы должны использовать механизм побега - это то, что говорит RFC:

Все символы Unicode могут быть размещены в кавычках, кроме для персонажей, которые должны быть экранированный: кавычка, обратный солидус и управляющие символы (От U + 0000 до U + 001F)

7 голосов
/ 29 января 2016

Я столкнулся с той же проблемой. Меня устраивает. Пожалуйста, проверьте это.

json_encode($array,JSON_UNESCAPED_UNICODE);
1 голос
/ 24 апреля 2019

Чтение json rfc (http://www.ietf.org/rfc/rfc4627.txt) ясно, что предпочтительной кодировкой является utf-8.

К вашему сведению, RFC 4627 больше не является официальной спецификацией JSON. В 2014 году он был отменен RFC 7159 , который затем был заменен в 2017 году RFC 8259 , который является текущей спецификацией.

RFC 8259 заявляет:

8,1. Кодировка символов

Текст JSON, которым обмениваются системы, не являющиеся частью замкнутой экосистемы, ДОЛЖЕН быть закодирован с использованием UTF-8 [RFC3629] .

Предыдущие спецификации JSON не требовали использования UTF-8 при передаче текста JSON. Однако подавляющее большинство программных реализаций на основе JSON решили использовать кодировку UTF-8, поскольку это единственная кодировка, которая обеспечивает совместимость.

Реализации НЕ ДОЛЖНЫ добавлять метку порядка байтов (U + FEFF) в начало передаваемого по сети текста JSON. В интересах совместимости реализации, которые анализируют тексты JSON, МОГУТ игнорировать наличие метки порядка байтов, а не рассматривать ее как ошибку.

0 голосов
/ 15 декабря 2015

У меня была похожая проблема с символом é char ... Я думаю, что комментарий "возможно, что текст, который вы вводите, это не UTF-8", вероятно, близок к отметке здесь. У меня есть ощущение, что сортировка по умолчанию в моем случае была чем-то другим, пока я не понял и не изменил на utf8 ... проблема в том, что данные уже были там, поэтому не уверен, преобразовал ли он данные или нет, когда я их изменил, в mysql отображается нормально верстак. Конечным результатом является то, что php не будет json кодировать данные, а просто возвращает false. Не имеет значения, какой браузер вы используете в качестве сервера, вызывающего мою проблему, php не будет анализировать данные в utf8, если этот символ присутствует. Как я говорю, не уверен, если это из-за преобразования схемы в utf8 после того, как данные присутствовали или просто ошибка php. В этом случае используйте json_encode(utf8_encode($string));

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...