I'm trying to make a Cross Origin post request, and I got it working in plain JavaScript
like this:
var request = new XMLHttpRequest(); var params = "action=something"; request.open('POST', url, true); request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");}; request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); request.setRequestHeader("Content-length", params.length); request.setRequestHeader("Connection", "close"); request.send(params);
But I would like to use jQuery
, but I can't get it to work. This is what I'm trying:
$.ajax(url, { type:"POST", dataType:"json", data:{action:"something"}, success:function(data, textStatus, jqXHR) {alert("success");}, error: function(jqXHR, textStatus, errorThrown) {alert("failure");} });
This results in Failure. If anyone knows why jQuery
doesn't work, please let us all know. Thanks.
(I'm using jQuery
1.5.1, and Firefox 4.0, and my server is responding with a proper Access-Control-Allow-Origin
header)
CORS is applied to requests when an Origin header is included in the request. This includes requests made from JavaScript and POST requests. It's not applied all resources.
Any CORS request has to be preflighted if: Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
To send a POST request using vanilla JavaScript, you can use an XMLHttpRequest object to interact with the server and provide the correct Content-Type request header for the POST message body data.
UPDATE: As TimK pointed out, this isn't needed with jquery 1.5.2 any more. But if you want to add custom headers or allow the use of credentials (username, password, or cookies, etc), read on.
I think I found the answer! (4 hours and a lot of cursing later)
//This does not work!! Access-Control-Allow-Headers: *
You need to manually specify all the headers you will accept (at least that was the case for me in FF 4.0 & Chrome 10.0.648.204).
jQuery's $.ajax method sends the "x-requested-with" header for all cross domain requests (i think its only cross domain).
So the missing header needed to respond to the OPTIONS request is:
//no longer needed as of jquery 1.5.2 Access-Control-Allow-Headers: x-requested-with
If you are passing any non "simple" headers, you will need to include them in your list (i send one more):
//only need part of this for my custom header Access-Control-Allow-Headers: x-requested-with, x-requested-by
So to put it all together, here is my PHP:
// * wont work in FF w/ Allow-Credentials //if you dont need Allow-Credentials, * seems to work header('Access-Control-Allow-Origin: http://www.example.com'); //if you need cookies or login etc header('Access-Control-Allow-Credentials: true'); if ($this->getRequestMethod() == 'OPTIONS') { header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); header('Access-Control-Max-Age: 604800'); //if you need special headers header('Access-Control-Allow-Headers: x-requested-with'); exit(0); }
Another possibility is that setting dataType: json
causes JQuery to send the Content-Type: application/json
header. This is considered a non-standard header by CORS, and requires a CORS preflight request. So a few things to try:
1) Try configuring your server to send the proper preflight responses. This will be in the form of additional headers like Access-Control-Allow-Methods
and Access-Control-Allow-Headers
.
2) Drop the dataType: json
setting. JQuery should request Content-Type: application/x-www-form-urlencoded
by default, but just to be sure, you can replace dataType: json
with contentType: 'application/x-www-form-urlencoded'
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