2010-08-09 74 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