Python CGI - UTF-8无效
关于HTML5和Python CGI:
如果我写了UTF-8的Meta标签,我的代码就不管用了。
如果我不写这个标签,它就能正常工作。
页面的编码是UTF-8。
print("Content-type:text/html")
print()
print("""
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
şöğıçü
</body>
</html>
""")
这段代码不管用。
print("Content-type:text/html")
print()
print("""
<!doctype html>
<html>
<head></head>
<body>
şöğıçü
</body>
</html>
""")
但是这段代码能正常工作。
2 个回答
10
来自 https://ru.stackoverflow.com/a/352838/11350
首先,别忘了在文件中设置编码。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
然后试试这个。
import sys
import codecs
sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
或者如果你使用的是apache2,可以把这个添加到你的配置文件中。
AddDefaultCharset UTF-8
SetEnv PYTHONIOENCODING utf8
10
在使用CGI的时候,调用 print()
函数需要确保输出的编码设置正确。print()
是往 sys.stdout
这个地方写东西,而 sys.stdout
是用特定的编码打开的,这种编码的选择跟你使用的操作系统有关,而且还可能因为脚本的运行方式不同而有所不同。当你把脚本作为CGI脚本运行时,你几乎无法知道会用什么编码。
在你的情况中,网络服务器已经把文本输出的编码设置成了固定的编码,而不是UTF-8。Python会根据这个设置来输出内容。如果没有 <meta>
头,浏览器会正确地猜测这个编码(或者服务器在Content-Type头中告诉了它),但如果有了 <meta>
头,你就告诉浏览器使用一个不同的编码,而这个编码对于生成的数据来说是不正确的。
你可以直接写入 sys.stdout.buffer
,但要先把内容编码成UTF-8。可以写一个辅助函数来简化这个过程:
import sys
def enc_print(string='', encoding='utf8'):
sys.stdout.buffer.write(string.encode(encoding) + b'\n')
enc_print("Content-type:text/html")
enc_print()
enc_print("""
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
şöğıçü
</body>
</html>
""")
另一种方法是用一个新的 io.TextIOWrapper()
对象 来替换 sys.stdout
,这个新对象使用你需要的编码:
import sys
import io
def set_output_encoding(codec, errors='strict'):
sys.stdout = io.TextIOWrapper(
sys.stdout.detach(), errors=errors,
line_buffering=sys.stdout.line_buffering)
set_output_encoding('utf8')
print("Content-type:text/html")
print()
print("""
<!doctype html>
<html>
<head></head>
<body>
şöğıçü
</body>
</html>
""")