这里接上篇:js中各种跨域问题实战小结(一)
后面继续学习的过程中,对上面第一篇有稍作休整。下面继续第二部分:
-->5.利用iframe和location.hash
-->6.window.name跨域实现
利用iframe和location.hash实现跨域
想必有很多人像我之前一样,或许只知道上面文中所说的那几种方法。所以,我刚了解到可以用iframe和location.hash来实现跨域的时候,我会想,为什么他们可以实现。iframe是什么,有什么特性,location.hash是什么又有什么特性。
准备:
>>1.MDN上说的<iframe>:HTML 的<iframe>(HTML inline框架元素)是一个嵌套的浏览上下文,他可以有效地嵌入另一个HTML页面到当前页面。在HTML 4.01中,一个文件可能包含一个头和一个身体或头部和一个框架集,而不是一个身体和一个框架集。然而,一个< iframe >可以被应用在正常的文件体。每个浏览上下文有它自己的会话历史和活动文档。浏览上下文包含嵌入的内容叫做父浏览上下文。顶级的浏览上下文(没有父)是典型的浏览器窗口。
了解到了<iframe>,我觉得另外两个相似的标签<frame>和<frameset>可以一起拿过来看下啦,这有篇文章放在一起总结了下:Frameset,Frame和Iframe
>>2.window.location:打开chrome的console,一起来试一下,很快就懂啦。我们从最基本的开始:
2.1 可以跳转到另一个页面:打开百度搜索的主页,然后在console中输入下面代码:
window.location = "http://www.cnblogs.com/skylar/";
看,是不是跳转到我的博客主页啦。
2.2 强制从服务器重新加载页面:既然来到了我的博客主页,就先别走,继续输入下面代码:
window.location.reload(true);
可以看到页面被重新加载了。
2.3 然后可以点击进去比如js中各种跨域问题实战小结(一)这篇文章,console输入:
location.hash = '#comments';
看看页面是不是跳到了最下面评论的位置。
其实还有两个特性:比如说alert当前url属性,通过修改window.location.search属性向服务器发送一个字符串,这你可以移步这里自行脑补:MDN window.location 。
这里有用的是下面这个例子:location.hash理解demo
这里可以查看代码:https://github.com/zhangmengxue,因为我们就是要利用location.hash的特性来加上iframe来实现跨域,看完了这个demo,我们就可以开始实现跨域了。(请用chrome打开,还有些需要总结的兼容性问题)
实现:
我为了模拟两个不同的域,在SAE上面创建了两个wordpress应用,如果你之前也不懂SAE是什么的话,这个小简介:新浪SAE 会让你大致了解到SAE是做什么的,如何开始使用它。我的两个应用:
看到url了吧,是不同域喔,环境模拟好了,我可以开始尝试跨域了。
在[http://1.daeskylar.sinaapp.com/]下有两个文件 a.html和c.html;
在[http://1.skylarisdae.sinaapp.com/]下有文件 b.html
我想要在a.html中访问我在b.html中模拟的数据Helloworld!
好呀,那现在点击 有a.html和c.html的这个域 访问我在这个域上的a.html文件,它应该会告诉你他是a.html页面,然后他会访问到了我放在b.html中的HelloWorld!
跨域这样就实现了喔,那具体是怎样实现的呢?
原理:
a.html想和b.html通信(在a.html中动态创建一个b.html的iframe来发送请求);
但是由于“同源策略”的限制他们无法进行交流(b.html无法返回数据),于是就找个中间人:与a.html同域的c.html;
b.html将数据传给c.html(b.html中创建c.html的iframe),由于c.html和a.html同源,于是可通过c.html将返回的数据传回给a.html,从而达到跨域的效果。
三个页面之间传递参数用的是location.hash,改变hash并不会导致页面刷新(这点很重要)。
------------------------------------------------------------------------------------------------------------------------------------------------
a.html---①--->b.html----②--->c.html---③--->a.html——>a.html便获得到了b.html中的数据
①通过iframe的location.hash传参数给b.html ;
②通过iframe的location.hash传参数给c.html ;
③同域传给a.html。
-------------------------------------------------------------------------------------------------------------------------------------------------
代码:
a.html:
1 <!doctype html> 2 <html> 3 <head> 4 <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" /> 5 <title>localhost:a.html</title> 6 7 <style type="text/css"> 8 9 </style> 10 </head> 11 12 <body> 13 <script type="text/javascript"> 14 alert('我是a页面'); 15 function sendRequest(){ 16 //动态创建个iframe 17 var ifr = document.createElement('iframe'); 18 ifr.style.display = 'none'; 19 //跨域发送请求给b.html,参数是#sayHello 20 ifr.src = 'http://1.skylarisdae.sinaapp.com/b.html#sayHello'; 21 document.body.appendChild(ifr); 22 } 23 function checkHash(){ 24 var data = location.hash?location.hash.substring(1):''; 25 if(data){ 26 //这里处理返回值 27 alert(data); 28 location.hash = ''; 29 } 30 } 31 setInterval(checkHash,1000); 32 window.onload = sendRequest; 33 </script> 34 </body> 35 </html>