我正在使用以下方法在python中开发一个小型Web服务:
我有一个自定义HTTP标头,Unison-UUID
我正在使用它来检索我的数据库中的信息。
这是(稍为简单的重写)片段,我遇到了麻烦:
uuid = flask.request.headers['Unison-UUID']
store = storm.locals.Store(my_database)
user = store.get(models.User, uuid)
班级User
或多或少是这样的:
class User(Storm):
uuid = Unicode(primary=True)
# Other columns....
上述代码以下列方式失败:
File "/Users/lum/Documents/unison-recsys/www/api/unison/unison.py", line 27, in decorated
user = g.store.get(models.User, uuid)
File "/Users/lum/Documents/unison-recsys/venv/lib/python2.6/site-packages/storm/store.py", line 165, in get
variable = column.variable_factory(value=variable)
File "/Users/lum/Documents/unison-recsys/venv/lib/python2.6/site-packages/storm/variables.py", line 396, in parse_set
% (type(value), value))
TypeError: Expected unicode, found <type 'str'>: '00000000-0000-0000-0000-000000000009'
我真的不明白为什么会这样,我能做些什么呢。我想Flask was 100% unicode。
我发现快速解决方法是解码标头值,即uuid = uuid.decode('utf-8')
。这真的需要做什么?这看起来有点骇人听闻。有没有办法直接获得unicode,而不必手动“解码”它?
答案 0 :(得分:13)
我们在http://flask.pocoo.org/docs/api/#flask.request阅读了
请求对象是
Request
子类的实例并提供 Werkzeug定义的所有属性。
单词Request
链接到我们阅读的http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers.Request
Request
和Response
类是BaseRequest
和。{BaseResponse
类和实现Werkzeug提供的所有mixins:
单词BaseRequest
链接到我们阅读的http://werkzeug.pocoo.org/docs/wrappers/#werkzeug.wrappers.BaseRequest
头
WSGI环境中的标头为不可变EnvironHeaders
。
单词EnvironHeaders
链接到我们阅读的http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.EnvironHeaders
这提供了与 Headers 相同的接口,并且是从WSGI环境构建的。
Headers 这个词是......不,它没有链接但它应该链接到我们阅读的http://werkzeug.pocoo.org/docs/datastructures/#werkzeug.datastructures.Headers
标题主要与Python
兼容wsgiref.headers.Headers
类
短语wsgiref.headers.Headers
链接到我们阅读的http://docs.python.org/dev/library/wsgiref.html#wsgiref.headers.Headers
创建一个类似于映射的对象包装头,它必须是一个列表 标题名称/值元组,如
PEP 3333
中所述。
短语PEP 3333
链接到http://www.python.org/dev/peps/pep-3333/,其中没有明确定义标题应该是什么类型但在搜索单词标题一段时间后我们发现此声明
因此,WSGI定义了两种“字符串”:"Native" strings (which are always implemented using the type named str) that are used for request/response headers and metadata "Bytestrings" (which are implemented using the `bytes` type in Python 3, and `str` elsewhere), that are used for the bodies of requests and responses (e.g. POST/PUT input data and HTML page outputs).
这就是为什么在Python 2中,标题为str
而不是unicode
。
现在让我们转向解码。
.decode('utf-8')
和男性.decode('ascii')
(也不是盲目地期待任何其他编码)都不是普遍好的,因为In theory, HTTP header field values can transport anything; the tricky part is to get all parties (sender, receiver, and intermediates) to agree on the encoding.。话虽如此,我认为你应该按照Julian Reshke的advice
因此,安全的方法是坚持使用ASCII,并在顶部选择编码 其中,例如RFC 5987中定义的那个。
检查您支持的用户代理(浏览器)是否已实现它。
RFC 5987的标题是超文本传输协议(HTTP)标头字段参数的字符集和语言编码
答案 1 :(得分:0)
标题值为ASCII,请参阅Acorn的链接问题。
你可以在这里做的是手动解码(尽管你应该使用uuid.decode('ascii')
而不是utf-8)或将你的字段更改为RawStr
而不是Unicode