我试图运行一个简单的'#hello world"使用mod_wsgi
进行Python 3的应用程序。我使用的是Fedora 23.这是我的Apache虚拟主机配置:
<VirtualHost *:80>
ServerName localhost
ServerAdmin admin@localhost
# ServerAlias foo.localhost
WSGIScriptAlias /headers /home/httpd/localhost/python/headers/wsgi.py
DocumentRoot /home/httpd/localhost/public_html
ErrorLog /home/httpd/localhost/error.log
CustomLog /home/httpd/localhost/requests.log combined
</VirtualHost>
wsgi.py:
def application(environ, start_response):
status = '200 OK'
output = 'Hello World!'
response_headers = [('Content-Type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
如果我将mod_wsgi
用于Python 2(sudo dnf remove python3-mod_wsgi -y && sudo dnf install mod_wsgi -y && sudo apachectl restart
),它可以正常工作,但是在使用Python 3时我得到500内部服务器错误。这里是错误日志:
mod_wsgi (pid=899): Exception occurred processing WSGI script '/home/httpd/localhost/python/headers/wsgi.py'.
TypeError: sequence of byte string values expected, value of type str found
更新
在encode()
上使用encode('utf-8')
(或str(len(output))
)也不起作用。现在我明白了:
Traceback (most recent call last):
File "/home/httpd/localhost/python/headers/wsgi.py", line 8, in application
start_response(status, response_headers)
TypeError: expected unicode object, value of type bytes found
答案 0 :(得分:24)
显然,变量output
本身需要一个字节字符串而不是一个unicode字符串。并且它不仅需要更改response_headers
,而且无处不在output
使用(因此第6行的str(len(output)).encode('utf-8')
将无法正常工作,就像I&I #39;一直在尝试。)
所以我的案例中的解决方案是:
def application(environ, start_response):
status = '200 OK'
output = b'Hello World!'
response_headers = [('Content-type', 'text/plain'),
('Content-Length', str(len(output)))]
start_response(status, response_headers)
return [output]
(我在官方mod_wsgi repo的one of the tests中找到了,正如Rolbrok在评论中所建议的那样。)
答案 1 :(得分:6)
背景
此问题是由于Python 3默认使用UTF-8引起的,因为今天我们发现有很多非本机英语字符,因此最好容纳它们。 HTTP仅适用于ASCII字符。它不能很好地处理UTF-8。因此,Apache和mod_wsgi都不适合UTF 8。
解决方案
因此,在准备好整个html字符串后,可以使用内置的python函数- bytes()进行类型转换。这需要一个字符串并给出一个字节字符串。
示例代码
html = "This "
html += "is the code"
html = bytes(html, encoding= 'utf-8')
response_header = [('Content-type', 'text/html')]
start_response(status, response_header)
yield html