window.name

I have learnt a lot of the last couple of days about inter-window and inter-iframe communication. I documented some of my frustrations about Web Messaging API’s and an attempted work around.

For you to be able to pass data into a window (that isn’t on your domain) so that it is available before the onload event fires in the opened window, the only sane way I have found is to set the window name via window.open.

Client:

var w = window.open("list.html", "some data");

Service:

window.onload = function () {  alert(window.name); };

Now that we can pass data between the windows, you can quickly imagine that you stringify a JSON object on open and parse it in the opened window. Pretty simple.

The good news is that the work-around works in FF, WebKit and Opera as is, but not IE.

To get it working with IE, it takes a few of hacks so I thought it best to document them here.

When you open a window via window.open, the second parameter is the name, in IE it must only contain [A-Za-z0-9_], this means that you have to base64 encode the JSON object for it to be able to be sent across, but that is not enough because Base64 encoding can only use certain characters. Base64 will also likely include an == at the end, which is not an allowed character.

However, IE doesn’t include a btoa and atob function for managing base64, so you will also need to find a library to use.

To encode the data I used the following:

var winname = window.btoa(
  unescape(
    encodeURIComponent(JSON.stringify(obj))
  )).replace(/=/g, "_")
var w = window.open(e.target.href, winname);

To decode the data I used the following:

var obj = JSON.parse(window.atob(window.name.replace(/_/g, "=")));

Pretty hacky, but it seems to work.

As always, if anyone has a better suggestion, or there are any obvious flaws let me know.