Monday, May 24, 2010

Cross Domain Ajax Request - Proxy, JSON style, FlXHR, XDR

Same origin policy is the security measures implemented by browser to to prevent a resource loaded from one site manipulating or communicating with another site. Due to same origin policy Cross domain ajax XHR(XMLHttpRequest) is not possible.



But now there are many ways to implement this. Some of them are -
1. Proxy
2. JSON with padding (JSONP)
3. Flash based - FlXHR
4. XDR XDomainRequest in Internet Explorer 8 (I have not tried this)

Proxy - This is the most comman approach. In this apporoach we send ajax request to our own domain and then send a backend request from our servert to another server, Now once we get a response we return it to the browser



Suppose abc.com application wants data from xyz.com in ajax look. App will send the request to abc.com server now abc.com server will send a backend request using any method to xyz.com and after getting the response it will return to the browser.
There is one more proxy solution - using apache's mod_rewrite or mod_proxy we can request from our server to another server.

JSON - This is also one way to do cross-site scripting by On-Demand Javascript. This is very simple method in which we have to insert a new script elements into our application DOM, with dynamically created src attributes. This look like an XMLHttpRequest().

But there is a limitation in this - other party's service has to return a valid JavaScript. It should supports some kind of JSONP reply structure, Means The reponse back will load a JSON object as a parameter of the callback function that we specified in our request. For example - Yahoo has implemented this feature in their web services API's.

http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=Madonna&results=2&output=json

Above url will return a valid JSON object, but if I append a callback param, then it will load this object as a parameter of my callback function. See the output of this -

http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=Madonna&results=2&output=json&callback=getMyData

Now, If we create an script element with this url as a source it will call the callback function with parameter of JSON output, now we have to only define the callback function and do the rest according to your need.
// Callback function
function getMyData(jsonData) {
alert('Titile = ' + jsonData.ResultSet.Result[0].Title + ' Summary = ' + jsonData.ResultSet.Result[0].Summary);
head.removeChild(script);
}

// Web service call
var req = 'http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=Madonna&results=2&output=json&callback=getMyData';
// Create a new request object
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= req;
head.appendChild(script);

Flash based -flXHR - flXHR is a client-based cross-browser, XHR-compatible tool for cross-domain Ajax. It utilizes an invisible flXHR.swf instance that acts as sort of a client-side proxy for requests, combined with a Javascript object/module wrapper that exposes an identical interface to the native XMLHttpRequest (XHR) browser object. I have just tried this and it is working perfectly fine. You have to do following thisngs only -
1- Download flXHR from http://flxhr.flensed.com/download.php
2- If you are using any library(jquery, prototype, dojo etc ) then it is good, there supports are also available.
In my case i tested it simply-
3- Extarct code, copy depoly folder on your app directory
4- On your page include flXHR.js
5 - Include this script code on your page

var ajobj = new flensed.flXHR();
ajobj.onreadystatechange = ajCallback;
ajobj.onerror = ajError;
ajobj.loadPolicyURL = "http://staging.itimes.com/crossdomain.xml";


function ajCallback(loadObj) {
if (loadObj.readyState == 4) {
alert(loadObj.responseXML);
alert(loadObj.responseText);
}
}
ajobj.open("POST","http://staging.itimes.com/flXHR-tests/xyz.php");
ajobj.send();

function ajError(errObj) {
alert("Error"+errObj);
}

6- Thing has to remember is on thirdparty.com root directory, there should be a crossdomain.xml which defines the acess somthing like -

cross-domain-policy
allow-access-from domain="mysite.com"
allow-http-request-headers-from domain="mysite.com" headers="*"
cross-domain-policy

Above are xml tag. Instead of mysite.com you can use * which will give access to all domain.

XDR - XDomainRequest is Cross-domain Request in Internet Explorer 8, It is one of the way to make anonymous requests to third-party sites that support XDR and opt in to making their data available across domains. It has two components: a client side that makes a request for data to a URL across domains, and a server side that responds with the Access-Control-Allow-Origin header of either * or the exact URL of the requesting page.IE8 to request data from the domain’s server by sending an Origin header with the serialized value of the origin of the requestor and response will return if server responds with Access-Control-Allow-Origin. You can read more about XDR - http://msdn.microsoft.com/en-us/library/dd573303%28VS.85%29.aspx

Practically I have not tried this but i'll try it soon.

3 comments: