Tornado Post Method Not Found

2020-03-04 10:06发布

问题:

I'm trying to post a form in Tornado web server but whenever I click submit the following error generates

405 Method Not Allowed

Here is the form

<form method="post">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="Submit">
</form>

I've tried changing the "get" method on the main Request Handler to "post" but it doesn't work. The only method that works is GET,

class MainHandler(BaseHandler):
    """
    Main request handler for the root path and for chat rooms.
    """

    @tornado.web.asynchronous
    def get(self, room=None):

Any suggestions?

回答1:

After that long window of chat I've figured that the best method for you specifically is to transfer the data through cookies.

Here's a tutorial: http://www.w3schools.com/js/js_cookies.asp

An alternative resource is to breakdown your data into multiple parts.

One approach would be to make a request to an end point that allocates you a unique ID. Then send a series of requests in the form: ?id=XXX&page=1&data=... before closing it with ?id=XXX&total_pages=27 at which point you assemble the different pieces on the server.



回答2:

The only method that works is GET because the only method you've defined on your handler subclass is get(). To handle POST, define a post() method instead of (or in addition to) get().



回答3:

I downloaded the sample project and ran it myself. I think I've made some progress.

First, the original MainHandler is not capable of handling POST request. According to the code, it handles request like /room/1, /room/2.

Second, I'm thinking that you are trying to mimic the login form. However the login form is using GET method and /login as endpoint:

<form class="form-inline" action="/login" method="get">

I guess that you also put your form in index.html, whose URL is actually /login(if not logged in) or /room/X(logged in). So you are probably hitting the LoginHandler.

Third, when I add a post method in MainHandler and send a POST request to /room/1, it's actually working and triggers a 500 Internal Error.

I use curl to test several cases. If you try to send a POST request to MainHandler on /, it doesn't even respond! Because, as mentioned before, get is defined as get(self, room=None). It only accepts /room/X.

If you try it on /room or /login, the response would be 405 Method Not Allowed.

If you want POST available for /login, the simplest way is to add POST in LoginHandler like this:

@tornado.web.asynchronous
def post(self):
    self.get()

# or this
post = get


标签: tornado