The other day we had a situation to implement a system which will be used by multiple partner's websites to interact with our client's server and exchange information. However this raises to the Same Origin Policy / Cross Origin Resource Sharing issues and we end up getting Request 405 errors (METHOD NOT ALLOWED). So before i go and tell you how we used easy XDM to solve this problem, let me give you an idea about what Same Origin Policy or CORS is
What is 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.[1] (Thanks to wikipedia)
What does this mean? This means that if you are on website A and you are using ajax to get information, then you can get information from within website A itself. However if you have Website B which wants data to Website A via Javascripts/Ajax, then the browsers will not let you do that act.
Why don't browsers let us do that? Simple answer, this gives opportunities to the hackers to hack into your websites and steal your sessions, cookie informatoin, etc., which are not supposed to be available to them.
But if i need to have a scenario where we are required to do that scenario, then what we should do? It is possible to by pass Same origin policy. There are many websites which allow information exchange between systems, for example flickr, can let you display your images on flickr account on your website. The same is case with Facebook, Twitter and many others. However you should know that you have to be careful when you are planning to execute this information. You might give away too much to the hackers.
Solutions/Workarounds to resolve Same Origin Policy
1. Using JSONP:- This is JSON with padding concept. Here it makes use of an extra call back variable along with the normal JSON calls which tells the server what kind of information we need to send back. However JSONP works only when it uses GET HTTP Request. it doesnot work for POST, PUT or DELETE.
2. Post Messaging :- This is an extension to JSONP and is implemented in most of the latest browsers i.e. IE9 onwards, Firefox 3.4 onwards, chrome and others support a new concept called as POST MESSAGING. this is achieved using Cross Origin Resource Sharing (CORS), where the users can make use of general XMLHTTPRequest i.e. AJAX request to achieve their goal. This is fastest and best concept involved. They also support POST, PUT and DELETE Http requests which are not supported by JSONP. However when it comes to supporting older versions of Browsers such as IE6, 7 and sometimes8 , firefox 3.1, etc., they fail
3. EasyXDM :- This solves both the problems of JSONP and POST MESSAGING. Easy XDM is one wrap around multiple systems to achieve a solution so that it is supported by all types of browsers, they internally use CORS / Post Messaging where ever the browsers support and if the browsers do not support they use Flash Message, Nix Message and Frame Element transports.
What is EASY XDM
As mentioned above EASY XDM is a wraparound on other tranports mechanisms to overcome Same Origin Policy, they use Post Message Transport for all the latest browsers and where ever they are not supported, they provide other types of transports. E.g. IE 6 and IE7 uses Nix Transport Flash Message Transport, Firefox older verisons use Frame Element Transport. More information of using EasyXDM and building systems using Easy XDM you could find at http://www.easyxdm.net. It has been beautifully written by Oyvind Kinsey from Norway. The following links would help you get started
You can download the code here http://github.com/oyvindkinsey/easyXDM
and after you download click here and start integrating.
once you are comfortable you can get to know about the features here and find more examples here .
Integrating EasyXDM for Ruby on Rails Applications
In order to explain how to build/integrate EasyXDM for Ruby on Rails applications. I would like to take an example of 2 ruby on rails applications one calling as PROVIDER and one as CO NSUMER (standard easyxdm concepts). I would run the Provider on localhost:3000 and run consumer on localhost:3005.
On the provider do the following activities
1. Copy the downloaded easy xdm code (if you have not already downloaded, you can download it here ). within your public folder. Do not place the folder within public/javascripts assuming it is a set of javascripts, but you will have to place it within the public folder.
2. You might want to whitelist your consumer in easyxdm (If you know your consumer) for safer actions. For that you need to add your consumer ip address / dns (e.g. localhost:3005) within easyxdm/cors/index.html
You might to add it in the following line
var alwaysTrustedOrigins = [(/\.?localhost:3005/), (/xdm1/)];
Once these 2 activities are completed your provider activity is done.
On the Consumer front you will have to do the following activities
1. check if you have correctly embedding the javascripts.
You have 2 options here.
a. Copy the EasyXDM folder in your consumer public directory and then link the javascripts as follows.
<script src="/easyxdm/easyXDM.debug.js" ></script> (on production replace it with <script src="/easyxdm/easyXDM.min.js" ></script> )
<script src="/easyxdm/json2.js" ></script>
b. You can call the Provider js files directly as
<script src="http://localhost:3000/easyxdm/easyXDM.debug.js" ></script> (on production replace it with <script src="/easyxdm/easyXDM.min.js" ></script> )
<script src="http://localhost:3000/easyxdm/json2.js" ></script>
Option b is necessary if your partner website is not ready to add additional folders within their website and they want everything to come in from Provider website.
2. Instantiating your EasyXDM Object ( i am currently instantiating RPC object)
<script>
var xdm = new easyXDM.Rpc({
local: "http://localhost:3000/easyxdm/name.html",
swf:"http://localhost:3000/easyxdm/easyxdm.swf",
remote: "http://localhost:3000/easyxdm/cors/",
remoteHelper: "http://localhost:3000/easyxdm/name.html"
}, {
remote: {
request: {} // request is exposed by /cors/
}
});
</script>
3. Once you have instantiated xdm object then you can use as below to make a
request do with the response
<script>
xdm.request({
url: "http://localhost:3000/MYCONTROLLER/MYACTION",
method: "POST",
data: {
key1:value1,
key2:value2,
key3:value3 //data that you want to receive in provider as part of params
}
},
function(response) {
alert(response.data); // response.data will give you what you sent from server. e.g. render :text=>"hello" or render :partial=>"somepartial"
});
</script>
Once you have implemented both consumer and provider, then it is just making use of the xdm object and making calls like just another AJAX request.
If you still have problems write to me at satishkota@heurion.com