【问题标题】:How to preserve UTF8 string from app to webserver in Python如何在 Python 中将 UTF8 字符串从应用程序保存到网络服务器
【发布时间】:2014-08-01 06:30:11
【问题描述】:

我有一个向 Python 网络服务器提交请求的应用程序。该应用程序有一个 UTF8 字符串,其内容如下:

法语语言.ppt

这被放入 HTTP 标头中,并以某种方式转换为:

法语语言\xfeaise.ppt

然后,网络服务器上的 Python 尝试对可能期望它是 UTF8 的字符串做一些事情,我得到了这个错误:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xfe in position 14: invalid start byte

我基本上想将这个 UTF8 从应用程序保存到网络服务器,这样如果我打印它,变量将包含以下内容:

法语语言.ppt

从 Web 客户端和服务器(假设都用 Python 编写)保留 UTF8 字符串的最佳方法是什么?

【问题讨论】:

  • 如果没有更多信息(您正在使用的网络服务器等),我无法给出准确的答案,但一种快速的解决方法是将字符串编码为 base64
  • @fileoffset 是一个django应用,有时在mod_wsgi下运行,有时在FCGI下,有时使用内置的appserver。我可能会尝试使用 base64 的东西,但我希望会有一种 Python 能够理解的“正常工作”的字符串转义。 Base64 的问题之一是它在快速检查服务器日志以查看传入的标头时变得无用。

标签: python utf-8


【解决方案1】:

\xfe 是 þ 的 ISO-8859-1 编码。

虽然 content 中的 utf8 得到广泛支持,但 HTTP headers 应该是 ASCII。 HTTP 规范允许 ISO-8859-1,但在工具中不推荐或不可靠。如果没有特殊转义,则不允许使用其他编码。

如果可能,请以允许它们作为 ASCII 传输的方式对特殊字符进行转义。 fileoffset 建议的 Base64 是一种选择,另一种是来自urllib.parse(或 python2 上的urrlib)的quote 函数

【讨论】:

    【解决方案2】:

    HTTP 标头是严格的 7 位 US ASCII。 RFC 允许您接受 ISO8859-1 作为兼容性黑客,但不要发送超过 127 的任何字节。

    在标头中发送除 ASCII 之外的任何其他数据类型没有标准或最佳方式。编码任意字节序列(并且您的 UTF 字符串是任意字节序列)是您的应用程序的责任,这样编码是 7 位安全的。

    使用对客户端和服务器最方便的实现语言。 Base64 编码、\hh 字节转义、\uhhhh unicofe 字符转义、根据 URL 编码的 %hh、MIME 中的 =HH 或 ... 实体。所有这些方法都存在并且正在广泛使用。

    【讨论】:

      【解决方案3】:

      尝试使用编解码器解码您的字符串:'iso-8859-1' 更多详情请查看here

      【讨论】:

        【解决方案4】:

        你有一个字节串(它已经解码)。

        要打印它,您需要先对其进行编码,以便组合 \xfe 可以翻译成其等效字符。

        为了知道\xfe 应该是什么,您需要在打印时告诉 Python 您希望使用的编码 - 您还需要确保打印它的位置(例如,在终端上) font 可以处理字符符号;否则你会得到垃圾输出。

        如果一切正常,您将获得以下信息:

        >>> i = "la langue fran\xfeaise.ppt"
        >>> print(i.decode('iso-8859-1'))
        la langue franþaise.ppt
        

        请注意,您的字符串不是 UTF-8 编码的,因此如果您尝试将其解码为 UTF-8,您会收到这个熟悉的错误:

        >>> print(i.decode('utf-8'))
        ...
        UnicodeDecodeError: 'utf8' codec can't decode byte 0xfe in position 14:
        invalid start byte
        

        要转换它,你首先必须从它的原始字符集解码它,然后将它重新编码为 utf-8:

        >>> z = i.decode('iso-8859-1').encode('utf-8')
        >>> z
        'la langue fran\xc3\xbeaise.ppt'
        >>> i
        'la langue fran\xfeaise.ppt'
        

        注意表示相同字符的字节的差异。最后,当您打印它时,它会正确打印(再次假设您的终端字体可以处理字形):

        >>> print(z.decode('utf-8'))
        la langue franþaise.ppt
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-19
          • 2022-12-14
          • 1970-01-01
          • 1970-01-01
          • 2012-03-13
          • 2014-06-12
          • 2011-02-19
          • 1970-01-01
          相关资源
          最近更新 更多