【问题标题】:latin1/unicode conversion problem with ajax request and special charactersajax 请求和特殊字符的 latin1/unicode 转换问题
【发布时间】:2011-02-15 20:57:24
【问题描述】:

服务器是 PHP5,HTML 字符集是 latin1 (iso-8859-1)。对于常规形式的 POST 请求,像 em dash (-) 这样的“特殊”字符没有问题。虽然我不确定,但它确实有效。可能是因为在字符代码 150 处存在浏览器的可表示字符(这是我在服务器上的 PHP 中看到的带有 ord 的文字破折号)。

现在我们的应用程序还通过 ajax 提供了某种预览机制:将文本发送到服务器,然后发送回用于预览的完整 HTML。但是,通过 ajax 发送的普通字符代码 150 em 破折号字符(使用 GET 和 POST 测试)会变异为更多内容:%E2%80%93。我已经在 apache 日志中看到了这一点。

根据我找到的各种来源,例如http://www.tachyonsoft.com/uc0020.htm,这是 em dash 的 UTF8 字节表示,我目前的知识是 JavaScript 处理 Unicode 中的所有内容。

但是在我的应用程序中,我需要所有 latin1 格式的内容。简单地说:就像一个常规的 POST 请求会给我那个破折号作为字符代码 150,我也需要它来翻译 UTF8 表示。

那是我失败了,因为当我尝试使用utf8_decode(...)iconv('UTF-8', 'iso-8859-1', ...) 对其进行解码时,服务器上有PHP,但在这两种情况下,我都会得到一个代表这个字符的常规?(并且iconv 也会抛出通知我:在输入字符串中检测到非法字符)。

我的目标是找到一个自动化的解决方案,但在这种情况下,也许我想变得更加聪明?

我发现其他人只是用预定义的输入/输出集进行手动替换;但这总是让我觉得我可以放松角色。

细心的读者会注意到,我在理解关于 Unicode 和字符转换的事情的全部影响/复杂性方面落后了,我绝对更愿意将事情作为一个整体来理解,而不是简单的手动映射。

根据 Delands 关于单字节字符必要性的问题进行更新:

说实话,我不知道我是否需要。目前,我有两种方法将数据传递到服务器并返回:

  1. 客户端 latin1 -> 正常发布请求 -> 服务器上的 latin1,以 latin1 发回完整页面,字符正常

  2. client latin1 -> ajax 请求(get 或 post) -> latin1 被转换为 utf8 -> 我尝试将 utf8 转换回 latin1 -> 将 latin1 HTML 片段发送到客户端以内联显示 -> 特殊字符失败

第二种方式失败,因为从 utf8->latin1 的转换不能像上面描述的那样使用 utf8_decode/icon 进行。

我的最终目标只是呈现用户输入的数据的预览。我需要服务器往返以进行 HTML 渲染和其他必须完成的数据评估。

解决方案

Alans 的答案是解决方案:latin1 在后面被视为windows-1252,这也是 Word(至少是我的 2007 年)在它和浏览器之间复制和粘贴内容时似乎使用的。

另一个有趣的链接(来自 Alans 维基百科文章)是 HTML 5 Syntax

8.2.2.2:用户代理必须至少支持 UTF-8 和 Windows-1252 编码,但可能支持更多。

...

如果用户代理将使用下表第一列中给出的编码来将内容转换为 Unicode 字符或将 Unicode 字符转换为字节,则它必须改为使用表格第二列中的单元格中给出的编码同一行。当一个字节或字节序列由于这种编码别名而被区别对待时,就被认为是为了兼容性而被误解了。

...

输入编码:ISO-8859-1 -> 替换编码:windows-1252

【问题讨论】:

    标签: php unicode utf-8 character-encoding latin1


    【解决方案1】:

    ISO-8859-1 不支持 em-dash 字符。您实际上正在使用 Microsoft 的扩展代码页之一,可能是windows-1252。它实际上是 latin1 的超集,因此当页面以 ISO-8859-1 提供时,浏览器倾向于使用它(这就是您的字符正确显示的原因)。但是,如果您要使用像 em-dash 这样的扩展字符,则应尽可能将 windows-1252 指定为字符集。或者,更好的是,在任何地方都指定 UTF-8。

    【讨论】:

    • 就是这样。成功的关键是要知道 latin1 默默地被视为 windows-1252。你摇滚,谢谢。
    【解决方案2】:

    包含 UTF-8 工作原理指南的页面:

    http://azabani.com/15

    https://en.wikipedia.org/wiki/UTF-8

    简而言之,“扩展”ASCII 集的映射并不容易,例如 ISO-8859-1(限制为 255 个代码点)和 Unicode(拥有 1114112 个代码点,使用了超过 100000 个代码点)。请详细说明为什么需要单字节字符集;也许我可以帮助你解决这个限制。 UTF-8 是编码文本最有效和最灵活的选择,应尽可能使用。

    【讨论】:

    • 感谢您的博客条目,关于组合/分解字符的信息非常丰富。关于您对单字节转换的询问,我已经更新了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 2022-07-21
    相关资源
    最近更新 更多