Outline
Did you ever try to create a widget like "Facebook Like Box" or whatever for your website? Did you try to include it in a foreign page with some JS code?
If you use iframes, this is trivial. But nobody ever wants iframes. We want to embed it properly.
But this is not as easy as it looks.
The idea
We want to enable all users to include such a small snippet on their own websites:
<div id="onlineWidget">
<script type="text/javascript" src="http://www.website.com/widgets/online.js"></script>
</div>
Lets say, we want to include it on the website "www.example.com"
If you develop locally, you will not discover any problems. But as soon as you put it online, nothing will work anymore.
The problem
A browser cannot include JS from a foreign domain (in this case "www.website.com") in his own source code at "www.example.com" and use ajax calls with this javascript code.
He will always get an empty result due to the "Same Origin Policy". It prevents possible security risks if the JS of the foreign website could actually call any url it wants.
Same goes for iframes by the way if you want to access the foreign content from the current location. Accessing it is possible, but changing the height of the iframe dynamically (based on the lenght of content) is not – because it would allow "editing" of the foreign iframe content.
Locally, it is always "localhost" as domain. So no problem there. On 2 websites in the internet, the domains will be different. Therefore you might be able to request something, but the browser will just omit any result.
The solution
We don’t use AJAX but dynamically rendered JS.
That’s possible because we can add JS files to the current DOM and the browser will open and execute the new JS code – or at least has access to it.
So we can use something like Hironori’s "JSONscriptRequest", which can be found here.
It uses dynamically generated script tags and some JSON.
Basic concept
It’s fairly simply: Trigger a click event on buttons and links which are caught in the included javascript. Build an url and submit it to the JSONscriptRequest script. This will then add the script into the html dom. With this technique you can dynamically add just about anything on any website.
Example
We might want to add a "name filter" in order to find only relevant friends who are online right now.
// inside document.ready()
jQuery("#filter-name").change(function() {
refreshContent(null);
});
function refreshContent() {
...
aObj = new JSONscriptRequest(href);
aObj.buildScriptTag();
aObj.addScriptTag();
}
and a little script to catch the inserted data and put it in the right space of your widget:
function result(jData) {
if (jData == null) {
alert('There was a problem parsing');
return;
}
// update div
content = jData.content;
jQuery('#onlineWidget').html(content);
}
How does it work?
When we include the widget from above we tell the browser to include a foreign javascript file. This itself can be a dynamically generated js file (depending on the url, the foreign server triggers specific actions and – with .js as extension – renders it as JS content. It now contains the desired content (sorted by name or whatever).
This content is embedded in the html of the website where we want to display the widget. Now we can access the javascript variables inside this new script and update the div container.
Yes, it can be dangerous
The author if this little script has put some warnings in his scripts:
A SECURITY WARNING FROM DOUGLAS CROCKFORD:
“The dynamic script tag hack suffers from a problem. It allows a page
to access data from any server in the web, which is really useful.
Unfortunately, the data is returned in the form of a script. That script
can deliver the data, but it runs with the same authority as scripts on
the base page, so it is able to steal cookies or misuse the authorization
of the user with the server. A rogue script can do destructive things to
the relationship between the user and the base server.”So, be extremely cautious in your use of this script.
Yes, it is avoiding the security measures set to prevent CRSF. But in this case we want to allow totally harmless widgets to work. The downside is, that you never know what pages contain harmful and what contain harmless widgets…