Cross-domain hash change communication

2019-01-24 19:15发布

问题:

Please consider the following two domains: domain1.com and domain2.

From domain1 I open an iframe that points to domain2.

Now, I want these guys to communicate with each other, which I've successfully accomplished by applying hash change event listeners on both domains.

That way, the hash in the parent window (domain1) will trigger if domain2 calls parent.location with a new hash. Also, the hash change event triggers in the iframe if I from the parent changes its src attribute to a new hash.

This works great!

Here comes the trouble:

The back and forward functionality in the browser gets messed up. Simply put, by creating two hash instances, the browser back button has to be clicked twice to get the parent hash to change since it has to cycle through the iframe's hash first.

How can I communicate with a cross-domain iframe 2-way without screwing up the history object?

Thanks!

回答1:

Use easyXDM, it's a javascript library that does all the hard work for you, enabling you to do cross-domain communication and RPC in all browsers, including IE6.

This will not use the HashTransport for any of the current browsers (not even IE6), and so will not change the history.

You will not find anything better..

You can read about some of its inner workings in this Script Junkie article, or go straight to the readme at github



回答2:

Another technique for crossdomain communications is (ab)using window.name. It requires an iframe to originally have a same-domain src initially after which you move to another domain that sets the window.name and then steps back to the original source (step back in history). The idea is that the window.name does not change unless it's explicitly set, this means you can transfer window.name data cross domain.

This technique is described in more detail on:
- http://skysanders.net/subtext/archive/2010/10/11/leveraging-window.name-transport-for-secure-and-efficient-cross-domain-communications.aspx
- http://jectbd.com/?p=611

Be sure to choose the implementation that avoids clicking sounds in IE.

Unfortunatly, it still messes around with your history, but it does a step forward and then backwards to the history point it was at. A big benefit though, is that you don't have to parse and encode URI strings, but can use JSON right away.

Using JSON lib for example

// access window.name from parent frame
// note: only when iframe stepped back to same domain.
var data = JSON.parse( iframe.contentWindow.name );

// set child frame name
// note: only when iframe stepped back to same domain.
iframe.contentWindow.name = JSON.stringify( {
    foo : "bar"
} ); // to JSON string

// set own name ( child frame )
window.name = JSON.stringify( {
    foo : "bar"
} ); // to JSON string

The cookie technique is viable as well, for both techniques you need to perform ajax requests in the target iframe if you want to avoid history changes but still require http request. so:

  1. Send data to iframe x (using cookie or window.name technique)
  2. Catch data with poller in iframe x
  3. Perform ajax requests in iframe x.
  4. Send data back to iframe y (using cookie or window.name technique)
  5. Catch data with poller in iframe y
  6. Do the hokey pokey.

Any page refresh (httprequest) or url change will update the history (except for old or all IE versions), so more code is required alas.