Обработка юникода в http ответе xml - PullRequest
2 голосов
/ 16 августа 2011

Я пишу расширение Google Chrome, основанное на API-интерфейсе REST myanimelist.net. Иногда текст ответа XMLHttpRequest содержит Unicode.


Например:

<title>Onegai My Melody Sukkiri&acirc;�&ordf;</title>


Если я создаю узел HTML из текста, он выглядит следующим образом:

Onegai My Melody Sukkiri�


Фактическое название, однако, таково:

Onegai My Melody Sukkiri♪


Почему мой текст отображается неправильно и как я могу это исправить?


Обновление

Код: background.html

Я думаю, что это важные части:

function htmlDecode(input){
  var e = document.createElement('div');
  e.innerHTML = input;
  return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}

function xmlDecode(input){
  var result = input;
  result = result.replace(/</g,  "&lt;");
  result = result.replace(/>/g,  "&gt;");
  result = result.replace(/\n/g, "&#10;");
  return htmlDecode(result);
}

Далее:

var parser = new DOMParser();
var xmlText = response.value;
var doc = parser.parseFromString(xmlDecode(xmlText), "text/xml");

Ответы [ 3 ]

2 голосов
/ 17 августа 2011
<title>Onegai My Melody Sukkiri&acirc;�&ordf;</title>

О, дорогой!Мало того, что это неправильный текст, это даже не правильно сформированный XML.acirc и ordf являются объектами HTML, которые не определены в XML, и между ними существует недопустимая последовательность UTF-8 (один старший байт, предположительно первоначально 0x99).

Проблема заключается в том, что myanimelistгенерировать их вывод «XML» (но «если он не правильно сформирован, это не XML») с использованием функции PHP htmlentities().Это пытается избежать HTML не только потенциально чувствительных в HTML символов <&"', но также и всех символов, не относящихся к ASCII.

Это создает неправильные символы, потому что PHP по умолчанию обрабатывает ввод для htmlentities() как ISO-8859-1 вместо UTF-8, которая является кодировкой, которую они фактически используют.Но с самого начала это было неправильно, поскольку в XML не существует набора сущностей HTML.Что они действительно хотели использовать, так это htmlspecialchars(), который оставляет символы не-ASCII в одиночестве, только избегая действительно чувствительных.Поскольку те же, что чувствительны в XML, htmlspecialchars() работает так же хорошо для XML, как и HTML.

htmlentities() почти всегда является неправильным;htmlspecialchars() обычно следует использовать вместо этого.Единственное место, где вы можете захотеть кодировать байты, не относящиеся к ASCII, к ссылкам на сущности, - это когда вы ориентируетесь на чистый вывод ASCII.Но даже тогда htmlentities() терпит неудачу, потому что он не делает ссылки на символы (&#...;) для символов, которые не имеют предопределенных имен сущностей.Довольно бесполезно.

В любом случае, вы действительно не сможете восстановить искаженные данные из этого. представляет последовательность байтов, которая была UTF-8-не декодируемой для XMLHttpRequest, так что информация безвозвратно утеряна.Вам нужно будет убедить myanimelist исправить их неверный вывод XML, как указано выше в нескольких параграфах, прежде чем идти дальше.

Кроме того, они должны возвращать его как Content-Type: text/xml, а не text/html на данный момент.,Тогда вы можете получить responseXML непосредственно из объекта XMLHttpRequest вместо того, чтобы возиться с DOMParsers.

1 голос
/ 16 августа 2011

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

Если вы посмотрите навозвращенное значение, которое вы разместили выше, вы заметите, скажем, сущность "â".99% времени, когда вы видите эту сущность, if означает, что у вас есть проблема с кодировкой символов (обычно символы UTF-8 кодируются как ISO-8859-1).

Первое, что я бы протестировал, - это принудительное кодирование символов в возврате API.(Это длинный выстрел, но вы можете посмотреть)

Во-вторых, я бы попытался принудительно ввести кодировку символов в возвращаемые данные (я знаю, что есть переопределение .htaccess, но я не знаю, что разрешено вРасширения Chrome, так что вам придется исследовать это).

Я думаю, что происходит, когда вы создаете узел с данными, у вас нет установленной кодировки символов в документе и браузерах(как правило, по моему опыту) по умолчанию ISO-8859-1.Итак, убедитесь, что проблема не в вашем документе.

Наконец, если вы не можете найти источник (или не можете предотвратить это) кодировки символов, вам нужно написатьтаблица разговоров для замены искаженных значений, которые вы получаете, на те, которые вы хотите {JS 'replace', должно быть в порядке (http://www.w3schools.com/jsref/jsref_replace.asp)}.

0 голосов
/ 16 августа 2011

Вы не можете просто использовать простой поиск и замену, чтобы исправить проблему с кодировкой, так как они представляют собой Unicode, а не символы, набранные на клавиатуре.

Ваши данные должны храниться на сервере в формате UTF-8, если вы планируете получать их через AJAX. Эта проблема, вероятно, связана с тем, что кто-то вставляет символы из MS-Word, использующие совершенно другую схему кодирования (ISO-8859).

Если вы не можете исправить данные, вы как бы облажались.

Подробнее см .: UTF-8 против Unicode

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