- 其他连接:
- 以下内容部分都摘自书本:《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
中
- 数据容量和类型都有限