【问题标题】:How do I convert a unicode header to byte string in Flask?如何在 Flask 中将 unicode 标头转换为字节字符串?
【发布时间】:2014-03-12 22:07:45
【问题描述】:

我有一个可以在我的开发服务器上运行的烧瓶应用程序。但是,当我尝试在 mod_wsgi 下运行相同的应用程序时出现错误:

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

我尝试了多种不同的方式转换标题,但我得到了同样的错误:

for k,v in dict(request.headers).iteritems():
    response.headers[k.encode('latin-1')] = v.encode('latin-1')

我也尝试了以下方法,但得到了完全相同的错误:

.encode('utf-8'), decode('utf-8'), decode('latin-1'), str()

我做错了吗?

编辑(真正的堆栈跟踪......我认为):

[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

编辑#2: 这是 Flask 中我试图获取令牌的视图以及我如何修改标头(或至少尝试):

@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

编辑#3(“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')]

【问题讨论】:

  • 你能分享完整的堆栈跟踪吗?
  • @metatoaster:添加了完整的堆栈跟踪。大多数日志记录来自 OAuthlib 和 Flask-OAuthlib
  • 虽然这不是一个完整的追溯;这仅显示异常行;剩下的就是记录其他地方的输出。
  • 我该怎么做?我是烧瓶和 python 的新手,对不起 ;(
  • 你试过在 mod_wsgi 上运行一个最小的“hello world”flask 应用程序吗?它会产生错误吗?见DebuggingTechniques

标签: python flask unicode http-headers


【解决方案1】:

怎么样

bytes(whatever_unicode.encode("utf-8"))

或根据 J.F. Sebastians 的评论

some_unicode.encode("ISO-8859-1")

或许

import urllib
urllib.quote(unicode_string)

其中一个应该可以工作......我认为

【讨论】:

  • bytes 在这里是多余的。默认情况下,http 标头使用ISO-8859-1 字符集,而不是utf-8。例如,all current desktop browsers support rfc 6266 and rfc 5987 to represent filenames with characters outside of ISO-8859-1
  • 谢谢@J.F.Sebastian!事实上,我将在我的答案中添加和扩展这一信息(尽管如果你用它来回答,我可能会删除我的答案并为你的答案投票)
  • 使用 urllib 引用会发生什么?
  • 同样的事情。我想我一定不能在烧瓶中正确修改标题。我的@app.after_request 中有这个功能
  • 添加一个我们可以重现的实际示例 .... 否则我不确定我能提供多少帮助(我不确定我能提供多少帮助)
【解决方案2】:

我在这个问题上纠结了很长时间。我对所选的答案一点也不满意。这是我在生产中所做的工作

@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

【讨论】:

    【解决方案3】:

    它正在工作!

    file = request.files.get('fileupload')
    
    file = StringIO(file.read().decode("ISO-8859-1"))
    

    【讨论】:

      猜你喜欢
      • 2017-04-16
      • 2013-02-05
      • 2012-11-30
      • 2015-05-01
      • 2013-08-21
      • 1970-01-01
      • 1970-01-01
      • 2014-06-29
      • 2021-05-11
      相关资源
      最近更新 更多