Php 带有ajax请求和特殊字符的拉丁1/unicode转换问题

Php 带有ajax请求和特殊字符的拉丁1/unicode转换问题,php,unicode,utf-8,character-encoding,latin1,Php,Unicode,Utf 8,Character Encoding,Latin1,服务器是PHP5,HTML字符集是latin1(iso-8859-1)。对于常规表单POST请求,例如em破折号(–)这样的“特殊”字符没有问题。虽然我不确定,但它是有效的。可能是因为浏览器的字符代码为150(这是我在服务器上的PHP中看到的带有ord的文本em破折号) 现在,我们的应用程序还通过ajax提供了某种预览机制:文本被发送到服务器,用于预览的完整HTML被发送回来。然而,当通过ajax(使用GET和POST测试)发送时,普通字符代码150 em破折号字符会变异成更多的字符:%E2%8

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

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

根据我找到的各种来源,例如,这是em-dash的UTF8字节表示,我目前的知识是JavaScript用Unicode处理一切

然而,在我的应用程序中,我需要所有的拉丁语1。简单地说:就像一个普通的POST请求会给我em破折号作为字符代码150一样,我也需要它来表示翻译后的UTF8

这就是我失败的原因,因为当我尝试使用
utf8\u decode(…)
iconv('UTF-8','iso-8859-1',…)
对服务器上的PHP进行解码时,在这两种情况下,我都会得到一个表示此字符的常规
(iconv也会提醒我:在输入字符串中检测到非法字符)

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

我发现其他人只是用预定义的输入/输出集手动替换;但那总是给我一种可以摆脱角色的感觉

细心的读者会注意到,我在理解Unicode和字符转换的全部影响/复杂性方面落后了,我肯定更喜欢从整体上理解,而不是简单的手动映射

基于德兰的更新关于单字节字符必要性的问题:

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

  • 客户端latin1->正常post请求->服务器上的latin1,以latin1返回完整页面,字符ok

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

  • 第二种方法失败,因为utf8->latin1的转换不能像上面使用utf8\u decode/icon所述那样工作

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

    解决方案

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

    更有趣的链接(来自Alans wikipedia文章)是:

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

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

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


    关于UTF-8工作原理的指南页面:


    简言之,像ISO-8859-1(限制在255个代码点)和Unicode(拥有1114112个代码点,其中使用了100000多个代码点)这样的“扩展”ASCII集并不容易映射。请告诉我为什么需要单字节字符集的更多细节;也许我能帮你克服这个限制。UTF-8是编码文本最有效、最灵活的选择,应尽可能使用。

    关于UTF-8工作原理的指南页面:


    简言之,像ISO-8859-1(限制在255个代码点)和Unicode(拥有1114112个代码点,其中使用了100000多个代码点)这样的“扩展”ASCII集并不容易映射。请告诉我为什么需要单字节字符集的更多细节;也许我能帮你克服这个限制。UTF-8是编码文本最有效、最灵活的选择,应尽可能使用。

    不支持em破折号字符。实际上,您可能正在使用Microsoft的一个扩展代码页。它实际上是latin1的超集,所以当一个页面被用作ISO-8859-1时,浏览器倾向于使用它(这就是为什么您的字符显示正确的原因)。但是,如果要使用扩展字符(如em破折号),则应尽可能将windows-1252指定为字符集。或者,更好的是,在所有地方指定UTF-8。

    不支持em破折号字符。实际上,您可能正在使用Microsoft的一个扩展代码页。它实际上是latin1的超集,所以当一个页面被用作ISO-8859-1时,浏览器倾向于使用它(这就是为什么您的字符显示正确的原因)。但是,如果要使用扩展字符(如em破折号),则应尽可能将windows-1252指定为字符集。或者,更好的是,在所有地方指定UTF-8。

    感谢您的博客文章,它提供了关于组合/分解字符的大量信息。我已经更新了关于您询问单字节转换的问题