mod_wsgi: TypeError: expected byte string object for header name, value of type unicode found

mod_wsgi: TypeError: expected byte string object for header name, value of type unicode found

我有一个 Flask Web 应用程序 运行 在生产环境中使用 Python 2.7.5 和 mod_wsgi 3.4。 Web 应用程序在生产和本地环回中运行良好。

我最近添加了一个 Flask Restplus API(3 种方法)。一切都在本地运行:我的 webapp 运行良好,3 个 Rest Api 方法正确响应,并且 swagger 文档 visible/working 在 /api/documentation.

但是在使用 mod_wsgi 的生产服务器上,我的 webapp 运行良好,我的其余部分 api 工作,但是如果我在 http://mydomain/api/documentation 访问 swagger 文档,我会收到两个错误httpd 错误日志:

Exception occurred processing WSGI script ...
TypeError: expected byte string object for header name, value of type unicode found

EDIT* 在访问日志中所有请求都是 200...唯一的 500 错误是由 /api/swagger.json...引起的 /api/documentation 甚至还有一个 200,这可能这就是为什么 swagger title 和 favicon 加载到浏览器选项卡中的原因,但在那下面是一条消息说 'No API Definition Provided'

我现在正尝试像这样设置响应 headers(使用 charset=UTF-8):

resp = app.response_class(
    response=json.dumps(found_resource),
    status=200,
    content_type='application/json; charset=UTF-8'
)
return resp

response = app.response_class(
    response=json.dumps({'success': False}),
    status=400,
    content_type='application/json; charset=UTF-8'
)
return response

我是否将 header 设置为字节字符串 object 以正确响应?任何响应都是 json 字典或 json 字典列表。

我有点困惑,因为这个 bug report 似乎不需要设置字符集,而且使用 content_type='application/json 可能是多余的;字符集=UTF-8

响应需要是实际的字节数组而不是字符串。您可以使用

response = app.response_class(
    response=bytes(json.dumps(found_resource).encode('utf-8')),
    status=200,
    content_type='application/json; charset=UTF-8'
)
return response

如果你切换到 Python 3,你可以使用 bytes(some_string, encoding='utf-8')

好的,在我的情况下...修复是使用 Flask 的@app.after_request.

设置 response.headers

显然 mod_wsgi 喜欢 unicode headers,但 HTTP 需要字节字符串。这是解决方案...没有它 mod_wsgi 将不会让 swagger.json 加载:

@app.after_request
def after(response):
    new_resp_headers = {}
    for k, v in response.headers.items():
        new_resp_headers[k.encode('ISO-8859-1')] = v.encode('ISO-8859-1')
    response.headers = new_resp_headers
    return response