龙卷风请求体

34

我的 Tornado 应用程序通过 HTTP 请求正文接受 POST 数据

在我的处理程序中,我能够获取请求

def post(self):
    data = self.request.body

我得到的数据以str(dictionary)的形式呈现。

有没有一种方法可以将这些数据以Python字典的形式接收?

我不想在服务器端使用eval将此字符串转换为Python字典。


你能发一个样例吗? - Blender
{ "_id": "cd4cca2_9vg5jyuwqxgmxfr", "time": '2012-01-01', "opening_type": "召回" } - Joel James
我正在对请求体进行JSON转储。json.dumps(self.request.body) - Joel James
让我们在聊天中继续这个讨论:http://chat.stackoverflow.com/rooms/29621/discussion-between-joel-james-and-blender - Joel James
Tornado并没有生成那个字符串,而是你的应用程序所接收到的内容。 - Cole Maclean
显示剩余4条评论
6个回答

53

除了Eloim的答案,Tornado提供了tornado.escape来进行"HTML、JSON、URL以及其他字符的转义和反转义"。使用它应该可以帮助你得到想要的结果:

data = tornado.escape.json_decode(self.request.body)

2
这对我不起作用 - 我收到错误:在json_decode中 返回json.loads(to_basestring(value)) 文件“/usr/lib/python3.6/json/init.py”中的第354行,载入 返回_default_decoder.decode(s) 文件“/usr/lib/python3.6/json/decoder.py”中的第339行,解码 obj,end = self.raw_decode(s,idx = _w(s,0).end()) 文件“/usr/lib/python3.6/json/decoder.py”中的第357行,原始解码 引发JSONDecodeError(“期望值”,s,err.value)from None json.decoder.JSONDecodeError:期望值:第1行第1列(字符0) - Charlie

23

14
在Python3中,您需要对原始的字节串进行解码,例如json.loads(self.request.body.decode('utf-8')) - 3k-
2
现在你可以使用tornado.escape.json_decode(self.request.body),它会为你处理所有的解码。 - Will S
请注意,使用tornado.escape包装器对json.loads进行编码意味着您将无法使用clsparse_... kwargs自定义/覆盖JSONDecoder。(这在使用互补的tornado.escape.json.encode包装json.dumps时更为严重,但在此处仍值得一提。) - cowbert

1

我在解析Tornado请求时遇到了类似的问题。尝试使用urllib.unquote_plus模块:

import urllib
try:
    import simplejson as json
except ImportError:
    import json


data = json.loads(urllib.unquote_plus(self.request.body))

我的代码必须准备好处理不同格式的请求,因此我做了以下操作:

try:
    json.loads(self.request.body)
except:
    json.loads(urllib.unquote_plus(self.request.body))

我很好奇答案是什么,所以如果这有帮助的话请告诉我(或者如果你在聊天中找到了答案)。我几乎可以确定这是因为它被URL编码了。 - Mitch
转义在这里帮了我。 - RandomInsano
1
对于Python3,它是urllib.parse.unquote_plus() - NuclearPeon

0
如果您正在使用WebApp2,它将使用自己的json extras。(解码) http://webapp2.readthedocs.io/en/latest/_modules/webapp2_extras/json.html
    data = json.decode(self.request.body)
    v = data.get(key)   
    self.response.write(v)

例如,我的帖子键是“postvalue”。
    data = json.decode(self.request.body)
    v = data.get('postvalue')   
    self.response.write(v)

0

怎么样?

bind_args = dict((k,v[-1] ) for k, v in self.request.arguments.items())

1
虽然这段代码可能回答了问题,但提供关于它如何或者为什么解决问题的额外背景信息将有助于提高答案的长期价值。 - Donald Duck
或者 { k : v[-1] for k, v in self.request.arguments.items() } - Jeppe

-1

在Tornado内置的httputil中解析主体的最佳方法
良好的多输入工作(如复选框、表格等)。 如果提交元素在字典中具有相同的名称,则返回值列表。

工作示例:

import tornado.httputil    

    def post(self):
        file_dic = {}
        arg_dic = {}

        tornado.httputil.parse_body_arguments('application/x-www-form-urlencoded', self.request.body, arg_dic, file_dic)

    print(arg_dic, file_dic)  # or other code`

这正是我正在寻找的,谢谢。 - royce3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接