gpt4 book ai didi

Python 3字节在CGI脚本中使用非ascii字符进行解码

转载 作者:行者123 更新时间:2023-12-01 01:51:51 25 4
gpt4 key购买 nike

我有一个非常短的示例代码:

print("Content-Type: text/plain; charset=utf-8")
print("Access-Control-Allow-Origin: *")
print()

x = 'Chloë'.encode()
print(x)
print(x.decode())

注意非 Ascii ë,这是所有问题的根源。

使用 python3 ./test.py 在 bash 中调用脚本会产生以下(正确的)输入:

Content-Type: text/plain; charset=utf-8
Access-Control-Allow-Origin: *

b'Chlo\xc3\xab'
Chloë

但是从浏览器调用它,最后一行不存在(标题当然不可见,但它们存在)。所以唯一可见的部分是:

b'Chlo\xc3\xab'

你知道哪里可能有问题吗?

最佳答案

您正在将 Unicode 打印到 sys.stdout 句柄(这是 print() 写入的默认文件对象)。然后,该对象必须再次对您的数据进行编码,但它必须根据它所连接的环境来进行编码。

当您运行python3 ./test.py时,您将连接到终端或控制台,并且通常将其配置为告诉脚本哪种编解码器合适。在 POSIX 系统(Linux、Mac)上,您可以运行 locale 命令来查看该配置是什么。在您的控制台区域设置中,显示像 ë 这样的非 ASCII 代码点没有问题。

但是当作为连接到网络服务器的 CGI 脚本运行时,不存在这样的语言配置,并且 Python 几乎肯定会回退到最低公分母:ASCII。在这种情况下,尝试打印非 Unicode 文本将导致异常:

$ LC_ALL="en_US.UTF-8" python3 -c "print(b'Chlo\xc3\xab'.decode())"
Chloë
$ LC_ALL="C" python3 -c "print(b'Chlo\xc3\xab'.decode())" # C => "no locale set"
Traceback (most recent call last):
File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xeb' in position 4: ordinal not in range(128)

由于异常仅在生成 header 和所有其他输出之后发生,因此您不会看到 HTTP 错误代码。但是,该异常应该已记录在您的服务器错误日志中。

如果您的脚本要按照您发出的 Content-Type header 中的配置将 UTF-8 输出到浏览器,请替换 sys.stdout 以强制使用该编解码器:

import sys
from io import TextIOWrapper

sys.stdout = TextIOWrapper(sys.stdout.buffer.detach(), encoding='utf8')

在 Python 3 中,用于 sys.stdout 流的文本文件包含一个缓冲区对象,该对象又包含一个负责实际二进制数据写入的二进制文件对象。实际上,外部文本文件对象只负责写入编码。上面的代码将该外部对象替换为始终编码为 UTF-8 的不同对象。

关于Python 3字节在CGI脚本中使用非ascii字符进行解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50642908/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com