Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery and Cross Domain POST Requests

I'm developing a jQuery plug-in that will be a connector for some REST API. The implementation is straight forward, but the same origin policy is definitely painfull. I need to perform mostly POST requests.

I also tried to implement the OPTIONS method and returning (is python, but the meaning should be clear)

def options(self):
  self.response.headers['Access-Control-Allow-Origin'] = self.request.host_url
  self.response.headers['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
  self.response.headers['Access-Control-Allow-Headers'] = 'x-requested-with'
  self.response.headers['Access-Control-Max-Age'] = '1728000'

still doesn't work... any idea ?

PS: I have seen that there are other question with a similar topic but i need a specific solution for POST method (GET could be easely implemented by using iframes)

Javascript example:

$.ajax({
    url: options.protocol+'://'+options.host+':'+options.port+'/'+method,
    data: rawData,
    async:false,
    dataType: "json",
    type:"POST",
    success:function(data)
    {
        alert('asd');
        result.data = data;
        alert(data);
    },
    error:function(lol){
        alert('omggg !!!!'+lol);
    }

});

EDIT: added javascript code example

like image 667
Cesar Avatar asked May 06 '11 07:05

Cesar


People also ask

Can you send an Ajax request to another domain?

Cross-origin resource sharing (or CORS) can be used to make AJAX requests to another domain.

How do I make a cross domain AJAX request?

Cross Domain AJAX Request. A common problem for developers is a browser to refuse access to a remote resource. Usually, this happens when you execute AJAX cross domain request using jQuery Ajax interface, Fetch API, or plain XMLHttpRequest. As result is that the AJAX request is not performed and data are not retrieved.

What is cross domain request in JavaScript?

Cross-Domain JavaScript Requests allow developers to work around security restrictions that would prevent an application from contacting Places (Search) API directly. For example, certain location information might not be retrievable without enabling this method.


1 Answers

It's a bit of a fiddle sometimes, some thoughts:

  • CORS is only supported by fairly modern browsers, so you'll need to be sure you're using one of those.
  • IE only supports CORS via the XDomainRequest object, not the standard XMLHttpRequest object, but jQuery doesn't specifically cater for that (yet; I have to admit I'm slightly surprised and expect it will before too long), so you have to add special handling to make this work on IE (and then only IE8 and above). Edit: Shockingly, apparently the jQuery team have had that request and denied it: ticket #8283 That makes no sense.
  • Are you sure about that Access-Control-Allow-Origin value? It looks like it's only allowing access from the server it's on. That header is meant to specify what origins the server will allow the request to come from. (And * is allowed, to mean "anywhere.")
  • I seem to recall from my experiments with Firefox on this that it was finicky about my allowing methods when responding to the OPTIONS request that it hadn't asked for.
  • Double-check that you're allowing all of the headers that the request is sending; in your example it looks like you're only allowing one header (x-requested-with), but I bet there will be others in the actual request.

FWIW (I'm not a Python guy), here's my JSP code that works, perhaps it will be useful — I think the object names are clear enough to be readable even if you don't do Java (and who knows, maybe you do):

String corsOrigin, corsMethod, corsHeaders;

// Find out what the request is asking for
corsOrigin = request.getHeader("Origin");
corsMethod = request.getHeader("Access-Control-Request-Method");
corsHeaders = request.getHeader("Access-Control-Request-Headers");
if (corsOrigin == null || corsOrigin.equals("null")) {
    // Requests from a `file://` path seem to come through without an
    // origin or with "null" (literally) as the origin.
    // In my case, for testing, I wanted to allow those and so I output
    // "*", but you may want to go another way.
    corsOrigin = "*";
}

// Add headers allowing specifically what was requested
response.addHeader("Access-Control-Allow-Origin", corsOrigin);
response.addHeader("Access-Control-Allow-Methods", corsMethod);
response.addHeader("Access-Control-Allow-Headers", corsHeaders);
if (request.getMethod().equals("OPTIONS"))
{
    // Done, no body in response to OPTIONS
    return;
}
// Processing the GET or POST here; output the body of the response

Note that I'm using exactly the same logic for GET, POST, and OPTIONS except that in the case of OPTIONS, I don't output a response body.

like image 57
T.J. Crowder Avatar answered Oct 31 '22 14:10

T.J. Crowder