问题
I have a flask app that I've been able to get running on my development server. However, when I try to run the same app under mod_wsgi I get an error:
TypeError: expected byte string object for header name, value of type unicode found
I've tried to convert the headers many different ways but I'm getting the same error:
for k,v in dict(request.headers).iteritems():
response.headers[k.encode('latin-1')] = v.encode('latin-1')
I've also tried the following but get the same exact error:
.encode('utf-8'), decode('utf-8'), decode('latin-1'), str()
Am I doing something wrong?
EDIT (the real stacktrace...I think):
[Wed Mar 12 23:26:49 2014] [notice] Apache/2.2.25 (Unix) mod_wsgi/3.4 Python/2.7.5 configured -- resuming normal operations
[Wed Mar 12 23:26:49 2014] [info] Server built: Sep 9 2013 06:59:27
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524834): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524834): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524835): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524835): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524833): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524833): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524832): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524832): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524831): Starting process 'api' with threads=1.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524831): Initializing Python.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524833): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524833): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524834): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524834): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524832): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524832): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524835): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524835): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524831): Attach interpreter ''.
[Wed Mar 12 23:26:49 2014] [info] mod_wsgi (pid=524831): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:51 2014] [info] mod_wsgi (pid=524833): Create interpreter 'web23.webfaction.com|'.
[Wed Mar 12 23:26:51 2014] [info] mod_wsgi (pid=524833): Adding '/path/to/api/lib/python2.7' to path.
[Wed Mar 12 23:26:51 2014] [info] [client 127.0.0.1] mod_wsgi (pid=524833, process='api', application='web23.webfaction.com|'): Loading WSGI script '/path/to/api/wsgi.py'.
[Wed Mar 12 23:26:52 2014] [error] [client 127.0.0.1] mod_wsgi (pid=524833): Exception occurred processing WSGI script '/path/to/api/wsgi.py'.
[Wed Mar 12 23:26:52 2014] [error] [client 127.0.0.1] TypeError: expected byte string object for header name, value of type unicode found
EDIT #2: Here's the view in Flask where I'm trying to get a token and how I'm modifying the headers (or, at least, trying to):
@app.route('/oauth/token/', methods=['GET','POST'],subdomain='api')
@oauth.token_handler # e.g. the decorator for OAuthlib/OAuthlib-Flask
def access_token():
return None
@app.after_request
def after(response):
import urllib
for k,v in dict(request.headers).iteritems():
response.headers[urllib.quote(k)] = urllib.quote(v)
return response
EDIT #3 ( output from "print dict(request.headers).items()" ):
[('Forwarded-Request-Uri', u'/oauth/token?client_secret=rDRzy2Qgt627dZK6eFtnylluOad7PRuLNUBothIpb0KQWJmOBl&grant_type=client_credentials&client_id=lryd8PqzlSObOQNUUEgEjqKYIeCnnkifs1s16NZ1'), ('Accept-Encoding', u'gzip, deflate, compress'), ('X-Forwarded-Host', u'api.example.com'), ('X-Forwarded-For', u'917.85.235.27'), ('Http-X-Forwarded-Proto', u'https'), ('Host', u'api.example.com'), ('Accept', u'*/*'), ('User-Agent', u'python-requests/2.2.1 CPython/2.7.5+ Linux/3.11.0-12-generic'), ('Connection', u'close'), ('X-Forwarded-Proto', u'https'), ('Https', u'on'), ('X-Forwarded-Server', u'api.example.com'), ('X-Forwarded-Ssl', u'on')]
回答1:
how bout
bytes(whatever_unicode.encode("utf-8"))
or per J.F. Sebastians comment
some_unicode.encode("ISO-8859-1")
or perhaps
import urllib
urllib.quote(unicode_string)
one of those should work ... I think
回答2:
I got stuck on this for a long time. I am not at all satisfied with the selected answer. Here's what I have working in production
@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
来源:https://stackoverflow.com/questions/22364955/how-do-i-convert-a-unicode-header-to-byte-string-in-flask