TypeError:期望的字节字符串值序列,找到的str类型的值

Sum*_*mit 12 python mod-wsgi python-3.x

我正在尝试使用mod_wsgiPython 3 运行一个简单的"hello world"应用程序.我正在使用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>
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

如果我使用mod_wsgiPython 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
Run Code Online (Sandbox Code Playgroud)

更新

使用encode()(或encode('utf-8'))on 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
Run Code Online (Sandbox Code Playgroud)

Sum*_*mit 27

显然,变量output本身需要一个字节字符串而不是一个unicode字符串.并且它不仅需要改变response_headers,而且需要在任何地方output使用(因此str(len(output)).encode('utf-8')第6行不会起作用,就像我一直在尝试的那样).

所以我的案例中的解决方案是:

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]
Run Code Online (Sandbox Code Playgroud)

(我在官方mod_wsgi repo的一个测试中找到了,正如Rolbrok在评论中所建议的那样.)


Rah*_*hul 8

背景

造成此问题的原因是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
Run Code Online (Sandbox Code Playgroud)