jQuery AJAX cross domain

JavascriptJqueryAjaxJsonCross Domain

Javascript Problem Overview


Here are two pages, test.php and testserver.php.

test.php

<script src="scripts/jq.js" type="text/javascript"></script>
<script>
    $(function() {
        $.ajax({url:"testserver.php",
            success:function() {
                alert("Success");
            },
            error:function() {
                alert("Error");
            },
            dataType:"json",
            type:"get"
        }
    )})
</script>

testserver.php

<?php
$arr = array("element1",
             "element2",
             array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>

Now my problem: when both of these files are on the same server (either localhost or web server), it works and alert("Success") is called; If it is on different servers, meaning testserver.php on web server and test.php on localhost, its not working, and alert("Error") is executing. Even if the URL inside ajax is changed to http://domain.com/path/to/file/testserver.php

Javascript Solutions


Solution 1 - Javascript

Use JSONP.

jQuery:

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

PHP:

<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>

The echo might be wrong, it's been a while since I've used php. In any case you need to output callbackName('jsonString') notice the quotes. jQuery will pass it's own callback name, so you need to get that from the GET params.

And as Stefan Kendall posted, $.getJSON() is a shorthand method, but then you need to append 'callback=?' to the url as GET parameter (yes, value is ?, jQuery replaces this with its own generated callback method).

Solution 2 - Javascript

JSONP is a good option, but there is an easier way. You can simply set the Access-Control-Allow-Origin header on your server. Setting it to * will accept cross-domain AJAX requests from any domain. (https://developer.mozilla.org/en/http_access_control)

The method to do this will vary from language to language, of course. Here it is in Rails:

class HelloController < ApplicationController
  def say_hello
    headers['Access-Control-Allow-Origin'] = "*"
    render text: "hello!"
  end
end

In this example, the say_hello action will accept AJAX requests from any domain and return a response of "hello!".

Here is an example of the headers it might return:

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive

Easy as it is, it does have some browser limitations. See http://caniuse.com/#feat=cors.

Solution 3 - Javascript

You can control this via HTTP header by adding Access-Control-Allow-Origin. Setting it to * will accept cross-domain AJAX requests from any domain.

Using PHP it's really simple, just add the following line into the script that you want to have access outside from your domain:

header("Access-Control-Allow-Origin: *");

Don't forget to enable mod_headers module in httpd.conf.

Solution 4 - Javascript

You need to have a look at Same Origin Policy:

> In computing, the same origin policy > is an important security concept for a > number of browser-side programming > languages, such as JavaScript. The > policy permits scripts running on > pages originating from the same site > to access each other's methods and > properties with no specific > restrictions, but prevents access to > most methods and properties across > pages on different sites.

For you to be able to get data, it has to be:

Same protocol and host

You need to implement JSONP to workaround it.

Solution 5 - Javascript

I had to load webpage from local disk "file:///C:/test/htmlpage.html", call "http://localhost/getxml.php" url, and do this in IE8+ and Firefox12+ browsers, use jQuery v1.7.2 lib to minimize boilerplate code. After reading dozens of articles finally figured it out. Here is my summary.

  • server script (.php, .jsp, ...) must return http response header Access-Control-Allow-Origin: *
  • before using jQuery ajax set this flag in javascript: jQuery.support.cors = true;
  • you may set flag once or everytime before using jQuery ajax function
  • now I can read .xml document in IE and Firefox. Other browsers I did not test.
  • response document can be plain/text, xml, json or anything else

Here is an example jQuery ajax call with some debug sysouts.

jQuery.support.cors = true;
$.ajax({
	url: "http://localhost/getxml.php",
	data: { "id":"doc1", "rows":"100" },
	type: "GET",
	timeout: 30000,
	dataType: "text", // "xml", "json"
	success: function(data) {
		// show text reply as-is (debug)
		alert(data);

		// show xml field values (debug)
		//alert( $(data).find("title").text() );

		// loop JSON array (debug)
		//var str="";
		//$.each(data.items, function(i,item) {
		//	str += item.title + "\n";
		//});
		//alert(str);
	},
	error: function(jqXHR, textStatus, ex) {
		alert(textStatus + "," + ex + "," + jqXHR.responseText);
	}
});

Solution 6 - Javascript

It is true that the same-origin policy prevents JavaScript from making requests across domains, but the CORS specification allows just the sort of API access you are looking for, and is supported by the current batch of major browsers.

See how to enable cross-origin resource sharing for client and server:

http://enable-cors.org/

"Cross-Origin Resource Sharing (CORS) is a specification that enables truly open access across domain-boundaries. If you serve public content, please consider using CORS to open it up for universal JavaScript/browser access."

Solution 7 - Javascript

This is possible, but you need to use JSONP, not JSON. Stefan's link pointed you in the right direction. The jQuery AJAX page has more information on JSONP.

Remy Sharp has a detailed example using PHP.

Solution 8 - Javascript

I use Apache server, so I've used mod_proxy module. Enable modules:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Then add:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

Finally, pass proxy-url to your script.

Solution 9 - Javascript

Browser security prevents making an ajax call from a page hosted on one domain to a page hosted on a different domain; this is called the "same-origin policy".

Solution 10 - Javascript

There are few examples for using JSONP which include error handling.

However, please note that the error-event is not triggered when using JSONP! See: http://api.jquery.com/jQuery.ajax/ or https://stackoverflow.com/questions/5247295/jquery-ajax-request-using-jsonp-error

Solution 11 - Javascript

From the Jquery docs (link):

  • Due to browser security restrictions, most "Ajax" requests are subject to the same origin policy; the request can not successfully retrieve data from a different domain, subdomain, or protocol.

  • Script and JSONP requests are not subject to the same origin policy restrictions.

So I would take it that you need to use jsonp for the request. But haven't tried this myself.

Solution 12 - Javascript

I know 3 way to resolve your problem:

  1. First if you have access to both domains you can allow access for all other domain using :

    header("Access-Control-Allow-Origin: *");

or just a domain by adding code bellow to .htaccess file:

<FilesMatch "\.(ttf|otf|eot|woff)$"> <IfModule mod_headers.c> SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0 Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin </IfModule> </FilesMatch>

  1. you can have ajax request to a php file in your server and handle request to another domain using this php file.
  2. you can use jsonp , because it doesn't need permission. for this you can read our friend @BGerrissen answer.

Solution 13 - Javascript

it works, all you need:

PHP:

header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');

JS (jQuery ajax):

var getWBody = $.ajax({ cache: false,
        url: URL,
        dataType : 'json',
        type: 'GET',
		xhrFields: { withCredentials: true }
});

Solution 14 - Javascript

For Microsoft Azure, it's slightly different.

Azure has a special CORS setting that needs to be set. It's essentially the same thing behind the scenes, but simply setting the header joshuarh mentions will not work. The Azure documentation for enabling cross domain can be found here:

https://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript

I fiddled around with this for a few hours before realizing my hosting platform had this special setting.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFirose HussainView Question on Stackoverflow
Solution 1 - JavascriptBGerrissenView Answer on Stackoverflow
Solution 2 - JavascriptjrhView Answer on Stackoverflow
Solution 3 - JavascriptAdorjan PrinczView Answer on Stackoverflow
Solution 4 - JavascriptSarfrazView Answer on Stackoverflow
Solution 5 - JavascriptWhomeView Answer on Stackoverflow
Solution 6 - JavascriptJasonView Answer on Stackoverflow
Solution 7 - JavascriptPaul SchreiberView Answer on Stackoverflow
Solution 8 - JavascriptimilbaevView Answer on Stackoverflow
Solution 9 - JavascriptJacob MattisonView Answer on Stackoverflow
Solution 10 - JavascriptBillyTomView Answer on Stackoverflow
Solution 11 - JavascriptWilliam ClemensView Answer on Stackoverflow
Solution 12 - JavascriptAli_HrView Answer on Stackoverflow
Solution 13 - JavascriptPaun Narcis IulianView Answer on Stackoverflow
Solution 14 - JavascriptJosh SchultzView Answer on Stackoverflow