一、基本原理
用location.hash解决域名完全不同的跨域,例如,http://www.baidu.com#helloworld中的"#helloworld"就是location.hash,改变hash值不会刷新页面,因此可以利用hash值来传递数据。
二、测试步骤
假设localhost:8080下的文件a.html要和localhost:8081下的文件b.html传递消息。
1、a.html首先创建一个隐藏的iframe,iframe的src指向localhost:8081/b.html,这时的hash值就可以做参数传递。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>不同域location.hash的a.html</title> </head> <body> <script> // http://localhost:8080/a.html let ifr = document.createElement('iframe'); ifr.style.display = 'none'; ifr.src = "http://localhost:8081/b.html#data"; document.body.appendChild(ifr); function checkHash() { try { let data = location.hash ? location.hash.substring(1) : ''; console.log('获得到的数据是:', data); }catch(e) { } } window.addEventListener('hashchange', function(e) { console.log('获得的数据是:', location.hash.substring(1)); }); </script> </body> </html>
2、b.html收到消息后通过parent.location.hash值来修改a.html 的hash值,从而实现数据传递。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>不同域location.hash的b.html</title> </head> <body> <script> // http://locahost:8081/b.html switch(location.hash) { case "#data": callback(); break; } function callback() { const data = "somenumber: 1111"; try { parent.location.hash = data; }catch(e) { // ie, chrome下的安全机制无法修改parent.location.hash // 所以要利用一个中间的代理iframe var ifrproxy = document.createElement('iframe'); ifrproxy.style.display = 'none'; ifrproxy.src = 'http://localhost:8080/c.html#' + data; //该文件在请求域名的域下 document.body.appendChild(ifrproxy); } } </script> </body> </html>
3、由于两个页面不在同一个域下,IE、Chrome不允许修改parent.location.hash的值,所以要借助localhost:8080域名下的一个代理iframe的c.html页面。
<script> parent.parent.location.hash = self.location.hash.substring(1); </script>
4、打开两个http服务器
5、打开浏览器访问localhost:8080/a.html,注意不是8081,就可以看到获取到的数据了,此时页面的hash值也已经改变。localhost:8080/a.html#somenumber:1111