Python WSGI内容编码

Python WSGI内容编码,python,http,utf-8,character-encoding,content-type,Python,Http,Utf 8,Character Encoding,Content Type,如果我执行以下Python 3.1程序,我只看到� 而不是我的浏览器中的正确字符。文件本身是UTF-8编码的,响应时发送相同的编码 from wsgiref.simple_server import make_server page = "<html><body>äöü€ßÄÖÜ</body></html>" def application(environ, start_response): start_response("200 Ok

如果我执行以下Python 3.1程序,我只看到� 而不是我的浏览器中的正确字符。文件本身是UTF-8编码的,响应时发送相同的编码

from wsgiref.simple_server import make_server

page = "<html><body>äöü€ßÄÖÜ</body></html>"

def application(environ, start_response):
    start_response("200 Ok", [("Content-Type", "text/html; charset=UTF-8")])
    return page

httpd = make_server('', 8000, application)
print("Serving on port 8000...")
httpd.serve_forever()

这里怎么了?

这些字符不是
UTF-8
;它们是
拉丁语-1
。如果将这些文本放入Python源代码中(您不应该这样做),则需要通过在顶部放置以下行来声明文件的编码:

#-*- coding: latin-1 -*-
并以拉丁语1提供服务:

start_response("200 Ok", [("Content-Type", "text/html; charset=latin-1")])
假设您打算在UTF-8中执行所有操作,则需要查找这些字符的代码点。然后你就可以做了

page = u"\x--\x--...\x--"
并将其作为Unicode提供


请注意,您可以通过更改浏览器的编码来验证这一点;如果手动将其更改为
latin-1
,字符将显示良好。

Python3上的WSGI尚不存在。Web SIG还没有就如何在Python3.x中处理字符串(字节/unicode)得出任何结论

wsgiref
主要是一种自动2to3转换;除了WSGI在3.x上的实际含义之外,它仍然存在一些问题。不要依赖它来参考WSGI应用程序在Python3下的工作方式

进入3.2发布周期的情况仍然是这样,这是令人尴尬和沮丧的

return page
虽然WSGI for 3.x仍然是一个未知因素,但有一点最为一致,即WSGI应用程序的响应体通常应该是字节,而不是unicode,因为HTTP是基于字节的协议。是否接受Unicode字符串,如果接受,将使用何种编码进行转换还有待观察,因此请避免此问题并返回字节:

return [page.encode('utf-8')]

(之所以需要
[]
,是因为WSGI应用程序应该返回一个一次输出并刷新一个项目的iterable。如果你自己传递一个字符串,它就被用作iterable,一次返回一个字符,这对性能很糟糕。)

我认为
-*-编码:…
不需要Python>=3。所示字符原则上可以直接用UTF-8书写。感谢您的启发。但是
returnpage.encode('utf-8')
不起作用。我从WSGI运行时收到以下错误:
AssertionError:write()参数必须是字符串或字节
。是的,很抱歉,我后来编辑了关于
[]
的部分!对于字节字符串而言,
[]
丢失的情况比unicode更难失败,因为在Python 3中,
b'A'[0]
是整数65,而不是
b'A'
。在我看来,这几乎是Python 3犯下的最严重的错误。我不会说这是一个错误。b“A”表示字节而不是字符是有道理的。这样一来,几乎不可能像以前那样混合使用str和unicode,我对python3.5也有同样的想法。我不知道是否有任何变化,但直到我在返回中完成page.encode,它才起作用。
return [page.encode('utf-8')]