2010-08-09 63 views
0

如果我执行下面的Python 3.1程序,我只在浏览器中看到 而不是正确的字符。该文件本身是UTF-8编码的,并且与响应一起发送相同的编码。WSGI内容编码

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” 设置正确的响应:

HTTP/1.0 200 Ok 
Date: Mon, 09 Aug 2010 16:35:02 GMT 
Server: WSGIServer/0.1 Python/3.1.1+ 
Content-Type: text/html; charset=UTF-8 

这里有什么问题?

回答

8

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

wsgiref很大程度上是一种自动2to3转换;即使除了3.x上WSGI的实际意义之外,它仍然存在问题。不要依赖它作为参考,如何WSGI应用程序将在Python 3下工作。

那情况是还是像这样进入3.2版本的发布周期是令人尴尬和沮丧的。

return page 

好,而对于WSGI 3.X仍是一个未知的因素,有一两件事最同意的是,一个WSGI应用程序的响应主体,一般应字节,不是Unicode,由于HTTP是一个基于字节,协议。无论是Unicode字符串将被接受,如果有什么编码他们会被转换成具有-还有待观察,所以要避免这个问题,并返回字节:

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

(需要的[]因为WSGI应用程序应返回如果你自己传递一个字符串,它被用作一个迭代器并且一次返回一个字符,这对性能来说是很糟糕的。)

+0

感谢您的启发。但'return page.encode('utf-8')'不起作用。我从WSGI运行时得到以下错误:'AssertionError:write()参数必须是一个字符串或字节'。 – deamon 2010-08-09 18:10:21

+0

它与'return [page.encode('utf-8')]'一起工作。 – deamon 2010-08-09 18:11:43

+1

是的,对不起,我后来编辑了一些关于'[]'的内容!缺少'[]'的情况比字符串更难以比unicode更好,因为在Python 3中,'b'A'[0]'是整数65,而不是'b'A''。几乎是Python 3最糟糕的错误,IMO。 – bobince 2010-08-09 18:44:17

0

这些字符不是UTF-8;他们是latin-1。如果你把那些文字到您的Python源代码(你不应该这样做),你需要申报文件的编码,通过将下面的行顶部:

#-*- coding: latin-1 -*- 

latin-1服务:

start_response("200 Ok", [("Content-Type", "text/html; charset=latin-1")]) 

假设你打算用UTF-8做所有事情,你需要查找这些字符的代码点。然后你可以做

page = u"\x--\x--...\x--" 

并将其作为Unicode提供。

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

+0

我以为'# - * - 编码:...在Python> = 3时不需要。所显示的字符可以直接用UTF-8编写。 – deamon 2010-08-09 17:43:09