Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cross domain ajax POST in chrome

There are several topics about the problem with cross-domain AJAX. I've been looking at these and the conclusion seems to be this:

Apart from using somthing like JSONP, or a proxy sollution, you should not be able to do a basic jquery $.post() to another domain

My test code looks something like this (running on "http://myTestdomain.tld/path/file.html")

var myData = {datum1 : "datum", datum2: "datum"}
$.post("http://External-Ip:port", myData,function(return){alert(return);});

When I tried this (the reason I started looking), chrome-console told me:

XMLHttpRequest cannot load http://External-IP:port/page.php. Origin http://myTestdomain.tld is not allowed by Access-Control-Allow-Origin.

Now this is, as far as I can tell, expected. I should not be able to do this. The problem is that the POST actually DOES come trough. I've got a simple script running that saves the $_POST to a file, and it is clear the post gets trough. Any real data I return is not delivered to my calling script, which again seems expected because of the Access-control issue. But the fact that the post actually arrived at the server got me confused.

  • Is it correct that I assume that above code running on "myTestdomain" should not be able to do a simple $.post() to the other domain (External-IP)?
  • Is it expected that the request would actually arrive at the external-ip's script, even though output is not received? or is this a bug. (I'm using Chrome 11.0.696.60 )
like image 603
Nanne Avatar asked May 09 '11 15:05

Nanne


People also ask

Can you do cross domain ajax?

You can allow Cross Domain Ajax calls to an application by just registering a new filter and then configure it to Allow-Origin : {your domain's} or you can use a wild card “*” to allow the calls from all domains.

Can ajax use post?

post() makes Ajax requests using the HTTP POST method. The basic syntax of these methods can be given with: $. get(URL, data, success); —Or— $.

What is post method in ajax?

Sends an asynchronous http POST request to load data from the server. Its general form is: jQuery. post( url [, data ] [, success ] [, dataType ] ) url : is the only mandatory parameter.


2 Answers

I posted a ticket about this on the WebKit bugtracker earlier, since I thought it was weird behaviour and possibly a security risk.

Since security-related tickets aren't publicly viewable, I'll quote the reply from Justin Schuh here:

This is implemented exactly as required by the spec. For simple cross-origin requests http://www.w3.org/TR/cors/#simple-method> there is no pre-flight check; the request is made and the response cannot be read if the appropriate headers do not authorize the requesting origin. Functionally, this is no different than creating a form and using script to make an off-origin POST (which has always been possible).

So: you're allowed to do the POST since you could have done that anyway by embedding a form and triggering the submit button with javascript, but you can't see the result. Because you wouldn't be able to do that in the form scenario.

A solution would be to add a header to the script running on the target server, e.g.

<?php
header("Access-Control-Allow-Origin: http://your_source_domain");
....
?>

Haven't tested that, but according to the spec, that should work.

Firefox 3.6 seems to handle it differently, by first doing an OPTIONS to see whether or not it can do the actual POST. Firefox 4 does the same thing Chrome does, or at least it did in my quick experiment. More about that is on https://developer.mozilla.org/en/http_access_control

like image 78
Marlies Avatar answered Sep 25 '22 03:09

Marlies


The important thing to note about the JavaScript same-origin policy restriction is that it is something built into modern browsers for security - it is not a limitation of the technology or something enforced by servers.

To answer your question, neither of these are bugs.

  • Requests are not stopped from reaching the server - this gives the server the option to allow these cross-domain requests by setting the appropriate headers1.

  • The response is also received back by the browser. Before the use of the access control headers 1, responses to cross-domain requests would be stopped dead in their tracks by a security conscious browser - the browser would receive the response but it would not hand it off to the script. With the access control headers, the server has the option of setting the appropriate headers indicating to a compliant browser that it would like to allow certain origin URLs to make cross domain requests.

    The exact behaviour on response might differ between browsers - I can't recall for sure now but I think Chrome calls the success callback function when using jQuery's ajax() but the response is empty. IIRC, Firefox will not invoke the success function.

like image 25
no.good.at.coding Avatar answered Sep 24 '22 03:09

no.good.at.coding