- 其他连接:
- 以下内容部分都摘自书本:《JavaScript高级程序设计(第3版)》 13.4.7 HTML5 事件
一、location.hash与iframe实现跨域

1.1 原理
1.2 步骤
- 假设
http://127.0.0.1:3001/a.html与http://127.0.0.1:3002/b.html需要实现通信。
http://127.0.0.1:3001/a.html
http://127.0.0.1:3001/a.html下嵌入一个iframe,其src为:http://127.0.0.1:3002/b.html
a.html发送数据数据给b.html,并修改iframe的src为http://127.0.0.1:3002/b.html#pro【#pro就是location.hash】
a.html在监听到url变化,并进行相应的操作
- 即:
a.html通过url的hash就可以拿到b.html传过来的数据
http://127.0.0.1:3002/b.html
b.html监听到url的变化,触发相应的操作
b.html传送数据到a.html,由于两个页面不在同一个域下IE、Chrome不允许修改parent.location.hash的值,所以要借助于父窗口域名下的一个代理iframe
b.html下创建一个隐藏的iframe,其src为:http://127.0.0.1:3001/proxy.html,并附加上要传送的数据,即iframe完整的src是:http://127.0.0.1:3001/proxy.html#data
try {
parent.location.hash = 'data';
} catch (e) {
// ie、chrome的安全机制无法修改parent.location.hash,
// 创建一个iframe
var ifrproxy = document.createElement('iframe');
// 隐藏iframe
ifrproxy.style.display = 'none';
ifrproxy.src = "http://www.baidu.com/proxy.html#data";
// 将iframe添加到页面,资源才可以加载
document.body.appendChild(ifrproxy);
}
http://127.0.0.1:3001/proxy.html
proxy.html监听到url的变化,就可以修改与其同域的a.html的url。
//因为parent.parent(即http://127.0.0.1:3001/a.html)和http://127.0.0.1:3001/proxy.html属于同一个域,所以可以改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);
1.3 location.hash的注意事项
HTTP请求过程中不会携带hash,所以修改hash不会产生HTTP请求
- 设置
location.hash 会在这些浏览器中生成一条新的历史记录
二、hashchange事件
hashchange事件:在 URL 的参数列表(及 URL 中“#”号后面的所有字符串)发生变化时通知开发人员。
- 新增这个事件的原因:在
Ajax 应用中,开发人员经常要利用 URL 参数列表来保存状态或导航信息。
- 支持
hashchange 事件的浏览器有 IE8+、Firefox 3.6+、Safari 5+、Chrome 和 Opera 10.6+。
- 只有 Firefox 6+、Chrome 和 Opera 支持
oldURL 和 newURL 属性。
hashchange 事件处理程序只能挂在 window对象下,然后 URL 参数列表只要变化就会调用它。
event 对象应该额外包含两个属性:
oldURL:保存着参数列表变化前的完整 URL 。
newURL:存着参数列表变化后的完整 URL。
EventUtil.addHandler(window, "hashchange", function(event){
alert("Old URL: " + event.oldURL + "\nNew URL: " + event.newURL);
})
//最好是使用 location对象来确定当前的参数列表。
EventUtil.addHandler(window, "hashchange", function(event){
alert("Current hash: " + location.hash);
});
var isSupported = ("onhashchange" in window); //这里有 bug
// 如果 IE8 是在 IE7 文档模式下运行,即使功能无效它也会返回 true。
var isSupported = ("onhashchange" in window) && (document.documentMode === undefined || document.documentMode > 7);
三、总结
location.hash和iframe跨域存在的问题:
- 这个方式的通信会造成一些不必要的浏览器历史记录
- 有些浏览器不支持
onhashchange事件,需要轮询来获知URL的改变
- 数据直接暴露在了
url中
- 数据容量和类型都有限