I have a simple tornado server which has the class:
class BaseHandler(tornado.web.RequestHandler):
def set_default_headers(self):
print "setting headers!!!"
self.set_header("Access-Control-Allow-Origin", "*")
When a regular (no CORS) request is made, the server answers as expected, including the Access-Control-Allow-Origin header. But when I make a post request coming from different domain (using jQuery.post
), the response is 404 and an error is displayed: "XMLHttpRequest cannot load http://dev-machine:8090/handshake. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8090' is therefore not allowed access. The response had HTTP status code 404."
Can you tell if I miss something? (another header/other configuration/anything else)
Simply add a header to your HttpServletResponse by calling addHeader : response. addHeader("Access-Control-Allow-Origin", "*");
You can either send the CORS request to a remote server (to test if CORS is supported), or send the CORS request to a test server (to explore certain features of CORS). Send feedback or browse the source here: https://github.com/monsur/test-cors.org.
Your code is missing preflight, the OPTIONS
request.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS:
The Cross-Origin Resource Sharing standard works by adding new HTTP headers that allow servers to describe the set of origins that are permitted to read that information using a web browser. Additionally, for HTTP request methods that can cause side-effects on user data (in particular, for HTTP methods other than GET, or for POST usage with certain MIME types), the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method. Servers can also notify clients whether "credentials" (including Cookies and HTTP Authentication data) should be sent with requests.
To implement preflight handler simply add options handler with the same headers and no body.
class BaseHandler(tornado.web.RequestHandler):
def set_default_headers(self):
print "setting headers!!!"
self.set_header("Access-Control-Allow-Origin", "*")
self.set_header("Access-Control-Allow-Headers", "x-requested-with")
self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
def post(self):
self.write('some post')
def get(self):
self.write('some get')
def options(self, *args):
# no body
# `*args` is for route with `path arguments` supports
self.set_status(204)
self.finish()
edit
I've added x-requested-with
header to allowed list. And here is simple jquery sample:
$.ajax({
url: "http://some_tornado/api",
type: "POST",
crossDomain: true,
data: 'some_data',
success: function (response) {
alert(response);
},
error: function (xhr, status) {
alert("error");
}
});
And some really good article about cors - http://dev.housetrip.com/2014/04/17/unleash-your-ajax-requests-with-cors/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With