CORS
HTML5 的 PostMessage API
Server Proxy
利用 iframe 和 location.hash
这个办法比较绕,但是可以解决完全跨域情况下的脚步置换问题。
原理是利用 location.hash 来进行传值。在 ‘http://a.com#helloword’ 中的 ‘#helloworld’ 就是location.hash,改变 hash 并不会导致页面刷新,所以可以利用 hash 值来进行数据传递,当然数据容量是有限的。
假设域名 a.com 下的文件 cs1.html 要和 cnblogs.com 域名下的 cs2.html 传递信息,cs1.html 首先创建自动创建一个隐藏的 iframe,iframe 的 src 指向 cnblogs.com 域名下的 cs2.html 页面,这时的 hash 值可以做参数传递用。
cs2.html 响应请求后再将通过修改 cs1.html 的 hash 值来传递数据,同时在 cs1.html 上加一个定时器,隔一段时间来判断 location.hash 的值有没有变化,有变化则获取获取 hash 值,代码如下:
先是 a.com 下的文件 cs1.html 文件:
function startRequest(){
var ifr = document.createElement('iframe');
ifr.style.display = 'none';
ifr.src = 'http://www.cnblogs.com/lab/cscript/cs2.html#paramdo';
document.body.appendChild(ifr);
}
function checkHash() {
try {
var data = location.hash ? location.hash.substring(1) : '';
if (console.log) {
console.log('Now the data is '+data);
}
} catch(e) {};
}
setInterval(checkHash, 2000);
cnblogs.com 域名下的 cs2.html:
//模拟一个简单的参数处理操作
switch(location.hash){
case '#paramdo':
callBack();
break;
case '#paramset':
// do something……
break;
}
function callBack(){
try {
parent.location.hash = 'somedata';
} catch (e) {
// ie、chrome 的安全机制无法修改 parent.location.hash,
// 所以要利用一个中间的 cnblogs 域下的代理 iframe
var ifrproxy = document.createElement('iframe');
ifrproxy.style.display = 'none';
ifrproxy.src = 'http://a.com/test/cscript/cs3.html#somedata';
// 注意该文件在"a.com"域下
document.body.appendChild(ifrproxy);
}
}
a.com 下的域名 cs3.html
// 因为 parent.parent 和自身属于同一个域,所以可以改变其 location.hash 的值
parent.parent.location.hash = self.location.hash.substring(1);
当然这样做也存在很多缺点,诸如数据直接暴露在了 url 中,数据容量和类型都有限等。