javascript 中 location.hash 是指 www.aa.com/a.php#abc中的#abc。
在本试验中,在局域网中用两台Windows 机器分别搭建了PHP的简单系统。通过设置 hosts 文件,使得A机器的系统网址为www.sso.com/SSO B机器系统网址为 www.javascript.com/SSO
本实验模拟的是 A 中通过IFrame将 B嵌入进来。然后A 每5秒钟查看A的hash值,并将hash值显示在A的页面中。
B页面在加载时就查看B的hash值,并根据hash值做出相应的动作。
总的交互过程为:
1. A 将B带有Hash值为 first的页面嵌入到Iframe中
2. B根据自己的Hash值去改变A的hash值
3. A又将A的hash值进行显示。
4. A 点击按钮,将B的hash值改成 second.
5. B发现B的hash值为Second,就调用callback2 函数,将A的hash值改成third
其中A通过setInterval(checkHash(), time) 函数进行定时查看A的hash值,并在checkHash中进行相关操作。在本实验中,checkHash将A的hash值进行显示。
A 的代码如下:
<html>
<h1>通过IFRAME 和 location.hash 进行javasript 跨域</h1>
<label id="label">ss</label>
<iframe id="iframe"></iframe>
<input type="button" onClick="changeValue()"/>
<script>
var iframe = document.getElementById('iframe');
startRequest();
setInterval(checkHash,5000);
function changeValue(){
iframe.src='http://www.javascript.com/SSO/index.php#second';
}
function startRequest(){
iframe.src='http://www.javascript.com/SSO/index.php#first';
}
function checkHash(){
var hash = location.hash?location.hash.substring(1):'';
var label = document.getElementById('label');
label.innerHTML += hash;
}
</script>
</html>
B 页面代码:
<html>
<script>
setInterval(checkHash, 10000);
function checkHash(){
switch(location.hash){
case '#first':callback();
break;
case '#second':callback2();
break;
}
}
function callback(){
alert('callback_one');
try{
parent.location.hash='second';
} catch(e){
var iframeProxy = document.createElement('iframe');
iframe='http://www.SSO.com/SSO/proxy.php#second';
document.body.append(iframe);
}
}
function callback2(){
alert('callback_two');
parent.location.hash='third';
}
</script>
</html>
在B的callback函数中,将位于 A域名下的proxy.php 页面嵌入到B的iframe中,并通过设置proxy.php 的Hash值,然后在proxy.php中将A的Hash值设置为和proxy.php一样的Hash值。proxy.php 在这里作为桥梁来改变 A的hash值。
通过测试,在Firefox 下不需要使用该proxy.php 作为桥梁,直接在B页面中通过parent.location.hash = 'XXX' 就可以改变B的父页面,也就是A页面的Hash值
但在 chrome 和 IE 下则需要使用 proxy.php
proxy.php 页面代码很简单:
<html>
<script>
parent.parent.location.hash = self.location.hash.substring(1);
</script>
</html>
其中parent.parent 就是A页面的window 对象
self是指proxy.php 本身的window对象