tornadoweb / tornado

Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed.
http://www.tornadoweb.org/
Apache License 2.0
21.78k stars 5.51k forks source link

"WARNING:tornado.access:405 OPTIONS" error will not allow POST #2104

Closed SephReed closed 7 years ago

SephReed commented 7 years ago

Testing with js, if I use an ajax call with "GET," it receives what it should. If I change it to "POST" an error is thrown on both client and server side.

The server side error is as follows WARNING:tornado.access:405 OPTIONS / (127.0.0.1) 2.12ms

I have tried running the ajax call both from file://index.html and localhost:8000/index.html with the same result in both cases.

SephReed commented 7 years ago

This has something to do with preflight of OPTIONS

bdarnell commented 7 years ago

This is a security measure that is working as intended. If you have a POST handler that you wish to make available cross-origin (and you understand the security implications of doing so), you must implement RequestHandler.options() accordingly. Read this MDN doc for more information.

SephReed commented 7 years ago

Leaving this here so people have a link to the tornado API for RequestHandler.options()

http://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler.options

Also, a link to the SO that helped me solve my problem:

https://stackoverflow.com/a/44901053/4808079

dexception commented 4 years ago

@bdarnell I am sorry i have to write this but you deserve a fucking yell from thousands of developers. You have just wasted countless hours for a situation that should be handled explicitly. Now for every code that you write people have to deal with your bullshit.

zhejunliux commented 3 years ago

I spent two hours,my solution,my code. my env:system==59~18.04.1-Ubuntu;python==3.6.12;tornado==6.1

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"/pullTop", MainHandler),
])

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