10

For some reason, I am not able to use POST methods in tornado.

Even the hello_world example does not work when I change GET to POST.

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def post(self):
        self.write("Hello, world")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

It throws "405 method not allowed". Any suggestions?

AreToo
  • 1,102
  • 11
  • 24
Divyanshu Das
  • 3,698
  • 4
  • 23
  • 27

4 Answers4

10

You still need get if you want access the page, because access the page using browser request with GET method.

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def post(self):
        self.write("Hello, world")
    get = post # <--------------

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • Making get and post behave the same is something I have to do often. Is writing get = post considered the correct way to do it? – andy boot Sep 30 '13 at 09:05
  • @andyboot, If behaviors of both methods are same, yes. – falsetru Sep 30 '13 at 09:08
  • this still doesn't work for me `WARNING:tornado.access:405 OPTIONS` tested from both `file://` and `localhost` – Seph Reed Jul 04 '17 at 07:37
  • @SephReed, Please post a separated question with details. BTW, `OPTIONS` , not `GET` ? Try `get = options = post` if you want OPTIONS http method. – falsetru Jul 04 '17 at 08:11
  • Yeah, it's pretty odd. I have the word OPTIONS literally nowhere. Question created: https://stackoverflow.com/questions/44900282/warningtornado-access405-error-stopping-post-from-both-localhost-and-file – Seph Reed Jul 04 '17 at 08:12
  • I can't believe this actually works... But it does and it just saved me some miserable hours of debugging ... – Kalin Varbanov Mar 06 '19 at 21:07
4

Falsetru answer is a useful hint and yes, what you need is exactly a get method. But no, I don't think get and post method should behave the same. The semantics of the two methods is different. Please have a look at the HTTP specs http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html and consider Brabster answer to this question What is the difference between a HTTP-Get and HTTP-POST and why is HTTP-POST weaker in terms of security.

(sorry, my sentence should be better a comment to falsetru answer but my reputation don't allow)

Community
  • 1
  • 1
1

recently, I have met the same problem. the following codes are my solutions:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
    print('set headers!!')
    self.set_header('Access-Control-Allow-Origin', '*')
    self.set_header('Access-Control-Allow-Headers', '*')
    self.set_header('Access-Control-Max-Age', 1000)
    self.set_header('Content-type', 'application/json')
    self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
    self.set_header('Access-Control-Allow-Headers',
                    'Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, X-Requested-By, Access-Control-Allow-Methods')


def OPTIONS(self):
    pass

def post(self):
    self.write("Hello, world")

application = tornado.web.Application([
(r"/", MainHandler),
])

if __name__ == "__main__":`enter code here`
 application.listen(8888)
 tornado.ioloop.IOLoop.instance().start()
Robert
  • 5,278
  • 43
  • 65
  • 115
LeeT
  • 39
  • 2
0

enter image description hereThe example code you gave in your question DOES work. Just be sure to send a POST instead of GET using Curl or Postman, for instance. If you point a web-browser to the URL it will attempt a GET, which you haven't defined.

You may not want to define a GET for the URL. It is perfectly legal to have a POST-only URL, and Tornado certainly allows you to. The POST url might be a common submission point for forms loaded from many other locations.

ChrisCantrell
  • 3,833
  • 1
  • 22
  • 14
  • 1
    It doesn't work. Please stop saying it works, because it doesn't, this problem is extremely annoying already. POST requests from either Postman or cURL don't work either. This is a deep issue within Tornado. – Sebastialonso Aug 28 '17 at 14:54
  • Well, I tested it once again on yet another machine. I copy/pasted the code from the question block. Then I ran it. Then I ran a POST with Postman in Chrome. Looks fine. When I change postman to do a GET on the example I get a 405 error. I'll try and paste an image in my original answer. – ChrisCantrell Sep 06 '17 at 16:06