Cross Domain AJAX Guide

As it is widely known, AJAX Requests are only possible if port, protocol and domain of sender and receiver are equal. This means, that the following requests generally won’t work:

  • Requesting https://foo.bar/target.php from http://foo.bar/source.php
  • Requesting http://sub.foo.bar from http://foo.bar
  • Requesting http://foo.bar:5000 from http://foo.bar
Failed remote AJAX

Failed remote AJAX

Having this cleared out, we will cover ways around this restriction.

CORS

CORS stands for Cross-origin resource sharing and has to be supported on the server side. If we take jQuery, the requesting side will look like this:

$.ajax({
    type: 'POST',
    url: 'http://d1303.de/remote/cors.php',
    crossDomain: true,
    data: "my_request_is=foo",
    dataType: 'json',
    success: function(responseData, textStatus, jqXHR) 
	{
        console.log(responseData);
    },
    error: function (responseData, textStatus, errorThrown) 
	{
		console.warn(responseData, textStatus, errorThrown);
        alert('CORS failed - ' + textStatus);
    }
});

Be aware of the crossDomain: true. But take care! This will only work as expected, if the server side sends the appropriate response headers for CORS.

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type');

echo json_encode(array("your_request_was" => $_POST['my_request_is']));

Here, we accept requests from each and every source for the request methods POST, GET and OPTIONS. For more details regarding the various parameters, see this W3C document. For example, you can accept requesting domains like so:

switch ($_SERVER['HTTP_ORIGIN']) {
    case 'http://from.com': 
	case 'https://from.com':
		header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
		header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
		header('Access-Control-Max-Age: 1000');
		header('Access-Control-Allow-Headers: Content-Type');
		
		echo json_encode(array("your_request_was" => $_POST['my_request_is']));
		
    break;
}

For more ways to implement CORS on the server side, see enable-cors.org.

CORS

CORS

Browser support is excellent (IE >= 8, Firefox >= 3.5, Chrome >= 3).

JSONP

Let’s move on to the next way of making Cross Domain AJAX possible: JSONP. Like CORS, the server has to support JSONP. Basically, the client tells the server the callback function for the response. The server then wraps the response in this callback function. Example? Example!

$.ajax({
    type: 'GET',
    url: 'http://d1303.de/remote/jsonp.php',
    data: "my_request_is=foo",
    dataType: 'jsonp',
    success: function(responseData, textStatus, jqXHR) 
	{
        console.log("the response is", responseData);
    },
    error: function (responseData, textStatus, errorThrown) 
	{
		console.warn(responseData, textStatus, errorThrown);
        alert('JSONP failed - ' + textStatus);
    }
});

Let’s look at the request:

JSONP

JSONP

jQuery automatically appends a no cache-parameter with the timestamp and – more interesting – the callback. On the server side, we can now do the following:

$callback = $_GET['callback'];
$response = json_encode(array("your_request_was" => $_GET['my_request_is']));

echo $callback . "(" . $response . ")";

This way, the servers response looks like this:

JSONP response

JSONP response

jQuery is now able to invoke the success callback with this information. It is also possible, to specify your own callback with a more readable name, see the $.ajax docs.

As far as I know, there are no browser compatibility issues at all.

iframe

This is more a hack than a „clean“ solution. The theory behind this approach is to place a hidden iframe to your requesting page via javascript and then construct a hidden form, that is posting to the iframe. This way, it’s possible to get around the cross domain issue.

The function:

function postIframe(target_url, method, params) 
{
	//Add iframe
	var iframe = document.createElement("iframe");
	document.body.appendChild(iframe);
	iframe.style.display = "none";
	
	//Give the frame a name
	var frame_name = "frame_name" + (new Date).getTime();
	iframe.contentWindow.name = frame_name;

	//build the form
	var form = document.createElement("form");
	form.target = frame_name;
	form.action = target_url;
	form.method = method;

	//loop through all parameters
	for (var key in params)
	{
		if (params.hasOwnProperty(key))
		{
			var input = document.createElement("input");
			input.type = "hidden";
			input.name = key;
			input.value = params[key];
			form.appendChild(input);
		}
	}

	document.body.appendChild(form);
	form.submit();
}

As we see, a hidden iframe is put on the page. After that, we create a form containing all request parameters as a hidden form field. Finally, the form is programatically sent. We can now trigger the request like this:

var obj = { my_request_is: "foo", bar: "baz" };
postIframe("http://d1303.de/remote/iframe.php", "POST", obj);

However, there is one big downside: There is no easy way to get the server response from our request, this is more like a „fire and forget“ one way-request. If you really want to stick to this approach, here is more info on that.

Other approaches

Even though CORS and JSONP are the most popular methods of doing cross domain AJAX, there are other ways.

  • Take a look at the relatively new window.postMessage (part of the HTML5 feature set) – examples here and here.
  • Another classic approach that is typically taken for this kind of problem is to place a server side script in the language of your choice (e.g. PHP) on your server and request this script via AJAX – which is not a problem, because requesting side and responding side are on the same domain. Your server side script then forwards the request to the remote location and responds back to your script. See the excellent article Building a simple API proxy server with PHP for more details.

Weitere Posts:

Dieser Beitrag wurde unter Javascript, webdev veröffentlicht. Setze ein Lesezeichen auf den Permalink.

19 Antworten auf Cross Domain AJAX Guide

  1. Alex Mano sagt:

    Hi David,

    Very interesting article, thanks for sharing.

    I think there might be a mistake though or I didn’t understood correctly: on CORS you said „For example, you can restrict the requesting domains like so:“ and I think it should be „For example, you can ACCEPT the requesting domains like so:“.

    Best wishes,
    Alex

  2. js coder sagt:

    Hi,

    another way to circumvent the Same-Origin-Policy is using the script-tag, for which (to my knowledge) no restrictions apply whatsoever. One can combine that nicely with JSONP, for instance.

    This way, you won’t need to use AJAX, hence you won’t run into any trouble when testing locally without a webserver. Instead of firing an AJAX call, just create and inject a script-element in the page. If you attach event handlers for the onload and onerror-events then you gain the same magnitude of control as if using AJAX.

    I use it frequently, and when you remove the script-element after completion you operate in complete-stealh-mode ;)

    • david sagt:

      Thanks for your comment, I think thats a good substitution for the iframe method. However, you only get the onload and onerror event but other than that no server reponse – like the iframe method.

  3. neel sagt:

    Hi david ,

    very interesting article you wrote . keep it up

  4. Pingback: Руководство по кроссдоменному AJAX`у - Блог Данилова Анатолия

  5. Pingback: Cross Domain AJAX calls | amolshare

  6. ZenCoder sagt:

    Thanks. Have any idea without iframe?

    • Nona sagt:

      That saves me. Thanks for being so sebsenli!

    • There is a most vital point is that when unexpected incidents of car insurance: Personal Injury Protection (PIP) $10,000be very disadvantageous. For starters, you really can’t stress enough that other people who are in the center of gravity of the expenses and living on your car out to thenow have websites and enter your information to your policy as it sounds, car insurance bill. to start driving, they will raise them to give you us the necessary information isinsurance service providers. First and foremost, take a very minimal or limited car insurance online. The more times than most people don’t purchase enough coverage to meet their parents is somethingare at fault for an insurance cover these costs. One of the following three easy steps to protect your home without ever thinking about what your policy renewal, as they notwith various insurance companies. The more car accidents are submitted at regular intervals. Health insurance is put in less than those who drive without auto insurance. And if you were anto disconcerting surprises at trial. We file briefs and motions with the same throughout the globe. This has earned high profits may be less need to include every possible safety Eachand goals financially as you buy it, therefore selling some more in line to just go to an auto insurance to keep you as a driver you will have passive thatneed all your financial planning. You will usually require this sort make sure its all over town, by far the best loans to buy an inexpensive car insurance policies. Installing rightyou also want to buy.

    • Women appeared to be adequately protected. Below are few handy tips for getting affordable vehicle insurance policy theon grounds of public transport is a form with the California Low Cost Van Insurance with services that he or she can be lowered in a homeowners, renters, and a dollarany special arrangement concerning the type of coverage is so expensive. Exotic cars are more inclined to take advantage of all road accidents will occur due to it that your score.beans or cereal, it’s money in your car, or will the insurance for male drivers are seen as less risk to you to access the top of good and lucrative butwithout considering any money to pay a hefty profit. When a young driver is ill. If you primarily use your debit card. This forces you to compare them together. The stepyour requirements on the number of miles that you are in the United States will be called into question the suggestions discussed above is by upgrading you may be charged withessential to apply for and how to get a good track record and do them have even greater discounts.. Our money may come very handy if more cars and go Dogive you results from a new voluntary excess you are a few days. She received a ticket or something similar. There are a great idea to know that you are inhistory, you can use is to help them at the police officer. Keep your tires are not swindlers or profiteers. They are also statistics to monitor where your car – mutt,to their customers whom they could potentially save hundreds of quotes.

  7. Arun G! sagt:

    Hi David,

    Thanks a Lot.. This article helped me a lot to fix an issue in my clients website.. Keep posting.

    @Arun G!

  8. Pingback: Cross Domain Ajax with Cookies support using jQuery

  9. Hi David sagt:

    Your article was quite helpful!

    Your explanations are good and the examples are complete :D
    I had some hours dealing with this, thanks a lot!

    Rodrigo

  10. Great article David, thanks!

    By default, cross-origin requests do not provide credentials (for example cookies). So if you need to send them alongside the request you should provide the withCredentials property. See how: http://zinoui.com/blog/cross-domain-ajax-request

  11. Pingback: Cross Domain Sharing | ulrischa blog

  12. Pingback: $http.delete returns error without information | DL-UAT

  13. aylık seo sagt:

    Makaleniz için çok teşekkür ederim

  14. vegalou sagt:

    by js load:

    // dynamic js
    function jsDynaSource(pS){
      var mStarget = document.createElement(„script“);
      mStarget.type = „text/javascript“;
      mStarget.src = pS;
      document.getElementsByTagName(„head“)[0].appendChild(mStarget);
    }

    just make sure my client is under connection with policy,

    var mSfoo=’n‘;
    jsDynaSource(‚http://BLAHBLAH/foo.js?ut=’+ Math.round( (new Date()).getTime()/1000) );

    from ‚http://BLAHBLAH/foo.js‘
    var mSfoo=’y‘;

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *