Tornado has correct request body, but cannot find correct arguments

我是研究僧i 提交于 2019-12-11 03:17:20

问题


Making a pretty straightforward Tornado app, but something that seems impossible is happening based on my understanding of Tornado. In short I've got the following RequestHandler:

class CreateUserHandler(tornado.web.RequestHandler):
    def post(self):
        print self.request.body
        print self.get_body_argument("email")
        # Do other things

And the following is what is printed:

{"email":"slater@indico.io","password":"password"}
WARNING:tornado.general:400 POST /user/create/ (::1): Missing argument email

So email clearly exists in the body, and yet when trying to access it a 400 is raised. I could manually parse the request body, but Tornado's error handling is nice enough that I'd like to avoid rewriting it if possible.

So, my basic question is how is this possible? It's printing the correct request body, and then is somehow unable to access the dictionary it just printed.


回答1:


get_body_argument is intended for form-encoded data, as you have discovered. Tornado has little support built-in for JSON data in request bodies. You can simply:

import json


class CreateUserHandler(tornado.web.RequestHandler):
    def post(self):
        data = json.loads(self.request.body)
        print data.get("email")



回答2:


Here's a little helper method I've been adding to my handlers in order to retrieve all of the body arguments as a dict:

from tornado.web import RequestHandler
from tornado.escape import json_decode

class CustomHandler(RequestHandler):

    def get_all_body_arguments(self):
        """
        Helper method retrieving values for all body arguments.

        Returns:
            Dict of all the body arguments.
        """
        if self.request.headers['Content-Type'] == 'application/json':
            return json_decode(self.request.body)
        return {arg: self.get_body_argument(arg) for arg in self.request.arguments}



回答3:


Not sure why this is the case, but I found a resolution. It required both url-encoding the body (this seems very strange to me as it's a request payload), and changing the Content-Type header to application/x-www-form-urlencoded

This is the new output of the script above:

email=slater%40indico.io&password=password
slater@indico.io


来源:https://stackoverflow.com/questions/40333280/tornado-has-correct-request-body-but-cannot-find-correct-arguments

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!