Introduction
Even though we, for security reasons, most often do not wish pages from different domains to be able to communicate, sometimes we do. And then, we discover that there is no 'proper' way to do so - the current standards and the current technologies are built to disallow it.
So we turn to workarounds, we use dynamic script tags included from external domains, we use JSONP, or we try our best using postMessage
or the IFrame
URL technique. These solutions often become quite complex and fragile, and transporting the pure string messages between the domains might very well end up making up most of your code.
Well, easyXDM (cross domain messaging) is now here, and it is meant to reduce the amount of work needed for cross-site communication - actually, it can do this in as little as 4 lines of code! And, if you want to be able to actually call methods across the boundary, well, that only takes 3 more!
See here for a demo of some of the functionality presented.
Background
This library was designed and built due to my company needing to expose an interface to one of our AJAX-applications. This application would have to be launched, and controlled to a certain degree from other web applications implementing our API, and our wish was to make it as reliable as possible (work both on IE6 and on FF3.5), and as easy to implement as possible. This has led us to easyXDM
, which we are now publishing under an MIT-license.
easyXDM
was previously called easyXDM
, but due to it often being mislabelled as malware (XSS), we decided to change its name.
The library lives at easyxdm.net, where you can easily get access to the source, ready made packages and also the extensive documentation. In the documentation you also find several interesting demos.
Using the Code
The code presented here assumes that you have a website with a method (an API, weather service, stock service ..) that you want to expose. In this example, the method is called _privateDoMagic
: it takes three arguments, and will return a JSON object.
What we want the API consumer to be able to do is call this method, like any other JavaScript method, and get the result back - something like this:
remote.doMagic('argument1',2,'three',function(result){
}
So first of all, we'll assume that the easyXDM
library is present on both the page providing the API and the page consuming it, and that the JSON object is also present in both, either natively or via the json2 library.
With easyXDM
you can actually use the following to load json2.js only when needed:
easyXDM.DomHelper.requiresJSON("/json2.js");
easyXDM
s base functionality is that it provides a reliable mechanism for transporting string
messages between domains, and it uses different techniques to do this depending on the browser.
But what easyXDM
is also able to do is to take an interface configuration, where you describe the methods you want to expose, and the methods you want to consume, and transform it into working code - easyXDM
does all the plumbing so that you can call the method in one domain, have the method call with arguments sent to the other domain, and have the result returned to the invoking method.
The interface is two-way, and both sides of the interface are able to expose and consume methods. The only difference in the configuration has to do with which side sets up the channel.
To expose the above-mentioned _privateDoMagic
method, so that it can be consumed, all we need to do is insert the following code:
var remote = new easyXDM.Interface({}, {
local: {
doMagic:{
method: _privateDoMagic
}
}
});
Here is the same code in a more compact form:
var remote = new easyXDM.Interface({},{local: {doMagic:{method: _privateDoMagic}}});
What we are doing here is creating a new
easyXDM.Interface, using default values for our
easyXDM.Channel, and an
InterfaceConfiguration exposing a single method.
By omitting the
settings for the channel, we are indicating that the library should use the default settings combined with the settings provided by the consumer.
That's all for the API provider!
Now, to consume this method, the following code is needed:
var remote = new easyXDM.Interface({
local: "../hash.html",
remote: "http://apiprovidersdomain.com/api.html"
},{
remote: {
doMagic: {}
}
});
And again in compact form:
var remote=new easyXDM.Interface({local:"../hash.html",
remote:"http://apiprovidersdomain.com/api.html"},{remote:{doMagic:{}}});
Again, we create an easyXDM.Interface
, this time supplying the channels configuration in the first parameter.
The supplied settings here are the path to the local copy of hash.html, and the URL to the API providers endpoint.
And that's it.
The consumer is now able to call the method locally using:
remote.doMagic('argument1',2,'three',function(result){
}
and have the result returned.
Good luck! Or actually, with this library, you don't need it! :)
Points of interest
If you look at the source code, you will actually see that the implementation is quite simple. It's also well documented, and experienced developers should be able to understand how it works quite easily.
The debug version includes extensive tracing, and you can easily see what's going on. This is used in the examples.
History
- 24th June, 2009: Initial post
- 14th August, 2009: Article updated