A common problem for every widget developer is getting data from the page to the server. The main obstacle is the cross-domain support or the lack there of. This is not as much as a problem when you’re sending small amounts of the data – you can load scripts from other domains sending the data through the GET request. A completely different story is the sending of lots of data, where you would normally need a POST request. Until now there were just a few possible solutions – use a Flash cross-domain bridge and build your own browser extension being the most prominent.
Now on you can easily use a new technique, first presented by Kris Zyp who wrote a dojo implementation for it. I was hoping that somebody would port this to other libraries but since nobody did I decided to do it myself. And a week later you can download the jQuery plugin.
Just include the plugin in your code and use the builtin $.ajax function as you would normally. It will automatically figure out if it needs to be run (POST to a foreign domain), otherwise it will let the original function handle the request.
- The first public release. It has been tested but not yet used in a production environment.
- The interval checking sometimes breaks the POST so no data is sent and the request returns an error.
- If you have a property called method, target or action this won’t work.
- Fixed issues with empty posts (timer removed)
- Fixed issues with method, submit, target, action data variables.
- windowname added to data now
- Window.name transport can now be requested via
- Tested with more data – works on IE7, IE8 (both Vista), Firefox2 (Vista), Firefox3 (OSX, Vista), Safari3 (OSX, Vista), Opera 9.5 (OSX, Vista), Chrome
- Added GET requests
- You can specify a local empty file that it will request after post to get data with a
- Fixed IE – if there’s a 404 on the requested local file and it’s too short IE will replace it with its own 404 which does not allow getting data from window.name
- Added the full BSD license of the dojo code
- Fixed a bug where + were left instead of spaces
- Fixed an IE bug when fields named method, action, target would throw an error
How it works
The plugin hijacks the $.ajax function and will do its magic when you’re POSTing to a foreign (domain not same as domain of document) domain or you specify
settings.windowname to force it. If these conditions are not met it will use the default ajax function to create the request.
The script first creates an iframe that will be the target of its request. If the request is of type GET it will open the location with the specified data as querystring in the iframe, if it’s a POST request it will first create a form with hidden fields that represent all data being sent. To allow sending of method, target, action and submit some magic is done (those override some important form object stuff) after which the form is posted to the iframe. This is
After the posted file is loaded (meaning it should have now set the window.name) an onload event is fired that loads an empty local file into the iframe. The empty local (same domain as the page) file can be set in the settings (
settings.localfile) – if it isn’t the script will first try loading /robots.txt and /crossdomain.xml (two files commonly found in the root that are small) and if both fail it will load the page it’s on. All this is done only on IE where 404 doesn’t count as local. This is
When the local file is loaded and it is surely local we can read the text from the
window.name. If it’s a string and it isn’t our default we set status to 200 and set the string as
responseText, otherwise we set a 502 status. We can now cleanup which means removing the form, the iframe and all references we created in the global space.
The whole thing is written in such a manner that it will return a fully qualified XMLHttpRequest object with all methods and properties. You can
abort the request and it will cancel loading and clean up, you can access readyState, responseText and everything else you’d do to an XHR object. It does however not implement features that cannot be used due to the fact that it’s an ordinary form submit – setting headers and such.
I’ve found that window.name transport is ideal for saving files – you can force the window.name transport to a url that will return a file with an Content-disposition: attachment; header. When the file loads you’ll get a popup to save it and the frame will disappear automatically. It’s even more convenient if you’re creating the file with a POST request.
As I intend to use this in a production environment I reckon most of the tweaks will come during testing and while in production. No new features are currently planned.
Kris Zyp wrote a great article about this and also contributed window.name transport to dojo.