[javascript] AJAX cross domain call

I know about AJAX cross-domain policy. So I can't just call "http://www.google.com" over a ajax HTTP request and display the results somewhere on my site.

I tried it with dataType "jsonp", that actually would work, but I get a syntax error (obviously because the received data is not JSON formated)

Is there any other possiblity to receive/display data from a foreign domain? iFrames follow the same policy?

This question is related to javascript jquery ajax json jsonp

The answer is


You can use the technology CORS to configure both servers (the server where the Javascript is running and the external API server)

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

p.s.: the answer https://stackoverflow.com/a/37384641/6505594 is also suggesting this approach, and it's opening the external API server to everyone else to call it.


I faced the same problem during 2 days and I found the solution, and it's elegant after googling a lot. I needed xss Ajax for some widget clients which pull datastream from tiers websites to my Rails app. here's how I did.


JSONP is the best option, in my opinion. Try to figure out why you get the syntax error - are you sure the received data is not JSON? Then maybe you're using the API wrong somehow.

Another way you could use, but I don't think that it applies in your case, is have an iFrame in the page which src is in the domain you want to call. Have it do the calls for you, and then use JS to communicate between the iFrame and the page. This will bypass the cross domain, but only if you can have the iFrame's src in the domain you want to call.


Here is an easy way of how you can do it, without having to use anything fancy, or even JSON.

First, create a server side script to handle your requests. Something like http://www.example.com/path/handler.php

You will call it with parameters, like this: .../handler.php?param1=12345&param2=67890

Inside it, after processing the recieved data, output:

document.serverResponse('..all the data, in any format that suits you..');
// Any code could be used instead, because you dont have to encode this data
// All your output will simply be executed as normal javascript

Now, in the client side script, use the following:

document.serverResponse = function(param){ console.log(param) }

var script = document.createElement('script');
script.src='http://www.example.com/path/handler.php?param1=12345&param2=67890';
document.head.appendChild(script);

The only limit of this approach, is the max length of parameters that you can send to the server. But, you can always send multiple requests.


I use this code for cross domain ajax call, I hope it will help more than one here. I'm using Prototype library and you can do the same with JQuery or Dojo or anything else:

Step 1: create a new js file and put this class inside, I called it xss_ajax.js

var WSAjax = Class.create ({
    initialize: function (_url, _callback){
        this.url = _url ;
        this.callback = _callback ;
        this.connect () ;
    },
    connect: function (){
        var script_id = null;
        var script = document.createElement('script');
        script.setAttribute('type', 'text/javascript');
        script.setAttribute('src', this.url);
        script.setAttribute('id', 'xss_ajax_script');

        script_id = document.getElementById('xss_ajax_script');
        if(script_id){
            document.getElementsByTagName('head')[0].removeChild(script_id);
        }

        // Insert <script> into DOM
        document.getElementsByTagName('head')[0].appendChild(script);
    },
    process: function (data){
        this.callback(data) ;
    }

}) ;

This class creates a dynamic script element which src attributes targets your JSON data provider (JSON-P in fact as your distant server must provide the data in this format :: call_back_function(//json_data_here) :: so when the script tag is created your JSON will be directly evaled as a function (we'll talk about passing the callback method name to server on step 2), the main concept behind this is that script like img elements are not concerned by the SOP constraints.

Step2: in any html page where you wanna pull the JSON asynchronously (we call this AJAJ ~ Asynchronous JAvascript + JSON :-) instead of AJAX which use the XHTTPRequest object) do like below

//load Prototype first
//load the file you've created in step1


var xss_crawler = new WSAjax (
     "http://your_json_data_provider_url?callback=xss_crawler.process"
 ,   function (_data){
            // your json data is _data and do whatever you like with it 
        }) ;

D'you remenber the callback on step 1? so we pass it to the server and it will returns the JSON embeded in that method so in our case the server will return an evalable javascript code xss_crawler.process(//the_json_data), remember that xss_crawler is an instance of WSAjax class. The server code depends on you (if it's yours), but most of Ajax data providers let you specify the callback method in parameters like we did. In Ruby on rails I just did

render :json=>MyModel.all(:limit=>10), :callback => params[:callback],:content_type => "application/json"

and that's all, you can now pull data from another domain from your apps (widgets, maps etc), in JSON format only, don't forget.

I hope it was helpfull, thanks for your patience :-), peace and sorry for code formatting, it doesn't work well


If you are using a php script to get the answer from the remote server, add this line at the begining:

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

You can use YQL to do the request without needing to host your own proxy. I have made a simple function to make it easier to run commands:

function RunYQL(command, callback){
     callback_name = "__YQL_callback_"+(new Date()).getTime();
     window[callback_name] = callback;
     a = document.createElement('script');
     a.src = "http://query.yahooapis.com/v1/public/yql?q="
             +escape(command)+"&format=json&callback="+callback_name;
     a.type = "text/javascript";
     document.getElementsByTagName("head")[0].appendChild(a);
}

If you have jQuery, you may use $.getJSON instead.

A sample may be this:

RunYQL('select * from html where url="http://www.google.com/"',
       function(data){/* actions */}
);

Unfortunately (or fortunately) not. The cross-domain policy is there for a reason, if it were easy to get around it then it wouldn't be very effective as a security measure. Other than JSONP, the only option is to proxy the pages using your own server.

With an iframe, they are subject to the same policy. Of course you can display the data from an external domain, you just can't manipulate it.


You will need to dynamically insert a script tag into the page that references the data. Using JSONP, you can execute some callback function when the script has loaded.

The wikipedia page on JSONP has a concise example; the script tag:

<script type="text/javascript" src="http://domain1.com/getjson?jsonp=parseResponse">
</script>

would return the JSON data wrapped in a call to parseResponse:

parseResponse({"Name": "Cheeso", "Rank": 7})

(depending on the configuration of the getjson script on domain1.com)

The code to insert the tag dynamically would be something like:

var s = document.createElement("script");
s.src = "http://domain1.com/getjson?jsonp=parseResponse";
s.type = "text/javascript";
document.appendChild(s);

after doing some research, the only "solution" to this problem is to call:

if($.browser.mozilla)
   netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');

this will ask an user if he allows a website to continue. After he confirmed that, all ajax calls regardless of it's datatype will get executed.

This works for mozilla browsers, in IE < 8, an user has to allow a cross domain call in a similar way, some version need to get configured within browser options.

chrome/safari: I didn't find a config flag for those browsers so far.

using JSONP as datatype would be nice, but in my case I don't know if a domain I need to access supports data in that format.

Another shot is to use HTML5 postMessage which works cross-domain aswell, but I can't afford to doom my users to HTML5 browsers.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to ajax

Getting all files in directory with ajax Cross-Origin Read Blocking (CORB) Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource Fetch API request timeout? How do I post form data with fetch api? Ajax LARAVEL 419 POST error Laravel 5.5 ajax call 419 (unknown status) How to allow CORS in react.js? Angular 2: How to access an HTTP response body? How to post a file from a form with Axios

Examples related to json

Use NSInteger as array index Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) HTTP POST with Json on Body - Flutter/Dart Importing json file in TypeScript json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 190) Angular 5 Service to read local .json file How to import JSON File into a TypeScript file? Use Async/Await with Axios in React.js Uncaught SyntaxError: Unexpected token u in JSON at position 0 how to remove json object key and value.?

Examples related to jsonp

CORS header 'Access-Control-Allow-Origin' missing JSONP call showing "Uncaught SyntaxError: Unexpected token : " jquery.ajax Access-Control-Allow-Origin Parse JSON response using jQuery parsing JSONP $http.jsonp() response in angular.js How can JavaScript save to a local file? Javascript search inside a JSON object IE9 jQuery AJAX with CORS returns "Access is denied" jquery how to use multiple ajax calls one after the end of the other Callback function for JSONP with jQuery AJAX