在http响应xml中处理unicode

Handling unicode in the http response xml

本文关键字:处理 unicode xml http 响应      更新时间:2023-09-26

我正在编写一个基于myanimelist.net RESTapi的GoogleChrome扩展。有时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");
<title>Onegai My Melody Sukkiri&acirc;�&ordf;</title>

天哪!这不仅是错误的文本,甚至不是格式良好的XML。acircordf是XML中没有预定义的HTML实体,它们之间有一个无效的UTF-8序列(一个高字节,可能最初是0x99(。

问题是myanimelist正在使用PHP函数htmlentities()生成他们的输出"XML"(但"如果格式不好,那就不是XML"(。这不仅试图对HTML中可能敏感的字符<&"'进行HTML转义,还试图对所有非ASCII字符进行HTML转义。

这会生成错误的字符,因为PHP默认将htmlentities()的输入视为ISO-8859-1,而不是他们实际使用的编码UTF-8。但一开始这是错误的,因为HTML实体集不存在于XML中。他们真正想要使用的是htmlspecialchars(),它只保留非ASCII字符,只转义真正敏感的字符。因为它们在XML中是敏感的,所以htmlspecialchars()对XML和HTML同样适用。

htmlentities()几乎总是错的;通常应使用CCD_ 9。当您的目标是纯ASCII输出时,您可能希望将非ASCII字节编码为实体引用。但即便如此,htmlentities()也会失败,因为它不会对没有预定义实体名称的字符进行字符引用(&#...;(。很没用。

无论如何,你真的无法从中恢复损坏的数据。表示一个对XMLHttpRequest不可编码的UTF-8字节序列,因此信息将无法修复地丢失。您必须说服myanimelist按照上面的几段修复他们损坏的XML输出,然后才能继续操作。

此外,他们应该将其返回为Content-Type: text/xml,而不是当前的text/html。然后,您可以直接从XMLHttpRequest对象中获取responseXML,而不用麻烦处理DOMParser。

所以,我遇到了一些类似于的东西,我做了更多的研究来证实我的假设。

如果您查看上面发布的返回值,您会注意到tell-tell实体"â"。99%的情况下,当你看到这个实体时,if意味着你有一个字符编码问题(通常UTF-8字符被编码为ISO-8859-1(。

我要测试的第一件事是在API返回中强制进行字符编码。(这是一个很长的机会,但你可以看看(

其次,我会尝试在返回的数据上强制使用字符编码(我知道有.htaccess覆盖,但我不知道Chrome扩展中允许什么,所以你必须对此进行研究(。

我认为,当你用数据封装节点时,文档上没有字符编码集,浏览器(根据我的经验,通常(默认为ISO-8859-1。因此,请检查以确保问题不是您的文档。

最后,如果你找不到字符编码的来源(或无法阻止它(,你就必须编写一个对话表,用你想要的值替换你得到的格式错误的值{JS'"替换"应该没问题(http://www.w3schools.com/jsref/jsref_replace.asp)}。

您不能只使用简单的搜索和替换来解决编码问题,因为它们是unicode,而不是键盘上键入的字符。

如果您计划通过AJAX检索数据,则数据必须以UTF-8格式存储在服务器上。这个问题可能是由于有人粘贴了来自MS Word的字符,这些字符使用了完全不同的编码方案(ISO-8859(。

如果你不能修复数据,你就有点完蛋了。

有关更多详细信息,请参阅:UTF-8与Unicode