博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js中各种跨域问题实战小结(二)
阅读量:5107 次
发布时间:2019-06-13

本文共 3590 字,大约阅读时间需要 11 分钟。

这里接上篇:

后面继续学习的过程中,对上面第一篇有稍作休整。下面继续第二部分:

 

-->5.利用iframe和location.hash

-->6.window.name跨域实现

 

 

利用iframe和location.hash实现跨域

想必有很多人像我之前一样,或许只知道上面文中所说的那几种方法。所以,我刚了解到可以用iframe和location.hash来实现跨域的时候,我会想,为什么他们可以实现。iframe是什么,有什么特性,location.hash是什么又有什么特性。

 

准备:

>>1.:HTML 的<iframe>(HTML inline框架元素)是一个嵌套的浏览上下文,他可以有效地嵌入另一个HTML页面到当前页面。在HTML 4.01中,一个文件可能包含一个头和一个身体或头部和一个框架集,而不是一个身体和一个框架集。然而,一个< iframe >可以被应用在正常的文件体。每个浏览上下文有它自己的会话历史和活动文档。浏览上下文包含嵌入的内容叫做父浏览上下文。顶级的浏览上下文(没有父)是典型的浏览器窗口。

了解到了<iframe>,我觉得另外两个相似的标签<frame>和<frameset>可以一起拿过来看下啦,这有篇文章放在一起总结了下:

 

>>2.:打开chrome的console,一起来试一下,很快就懂啦。我们从最基本的开始:

2.1 可以跳转到另一个页面:打开百度搜索的主页,然后在console中输入下面代码:

window.location = "http://www.cnblogs.com/skylar/";

看,是不是跳转到我的博客主页啦。

2.2 强制从服务器重新加载页面:既然来到了我的博客主页,就先别走,继续输入下面代码:

window.location.reload(true);

可以看到页面被重新加载了。

2.3 然后可以点击进去比如这篇文章,console输入:

location.hash = '#comments';

看看页面是不是跳到了最下面评论的位置。

其实还有两个特性:比如说alert当前url属性,通过修改window.location.search属性向服务器发送一个字符串,这你可以移步这里自行脑补: 。

这里有用的是下面这个例子:

这里可以查看代码:,因为我们就是要利用location.hash的特性来加上iframe来实现跨域,看完了这个demo,我们就可以开始实现跨域了。(请用chrome打开,还有些需要总结的兼容性问题)

 

 

实现:

我为了模拟两个不同的域,在SAE上面创建了两个wordpress应用,如果你之前也不懂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文件,它应该会告诉你他是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  2  3  4 
5 localhost:a.html 6 7 10 11 12 13 34 35
View Code

c.html:

1  2  3  4 
5 localhost:c.html 6 7 10 11 12 13 17 18
View Code

b.html:

1  2  3  4 
5 另某个域的:b.html 6 7 10 11 12 13 36 37
View Code

 

这里参考了:

 

利用window.name实现跨域

 

实现:

我还是利用上面我在sae上面创建的应用:

在[http://1.daeskylar.sinaapp.com/]下有两个文件 wantdata.html和proxy.html;

在[http://1.skylarisdae.sinaapp.com/]下有文件 data.html。

我想要在wantdata.html中访问到我在data.html中存在window.name中的数据,是个字符串,就叫‘我拿到数据啦!’。

访问这里: 应该可以看到alert出的数据喔。

 

原理:

是这样说的:

窗口的名称,主要用于设置超链接和表格对象。Windows不需要有名字。

它也被用于提供跨域通信的一些框架(例如,sessionvars和Dojo的DojoX。IO。windowname)为JSONP更安全的替代方案。

 

window.name 的美妙之处在于:name 值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。

这篇文章讲解的非常详细,很值得阅读:

 

实现起来基本步骤如下: 

     1.创建一个iframe,把其src指向目标页面(提供web service的页面,该目标页面会把数据附加到这个iframe的window.name上,大小一般为2M,IE和firefox下可以大至32M左右;数据格式可以自定义,如json字符串);

     2.监听iframe的onload事件,在此事件中立即设置这个iframe的src指向本地域的某个页面,由本地域的这个页面读取iframe的window.name。

     3.获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)。

总结起来即:iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。

 

代码:

wantdata.html

1  2  3  4 
5 window.name跨域demo 6 7 10 11 12 13 37 38
View Code

data.html

1  2  3  4 
5 data页 6 7 10 11 12 13 17 18
View Code

proxy.html

1  2  3  4 
5 window.name跨域demo 6 7 10 11 12 13 这里是代理空文件14 17 18
View Code

 

 这里参考了:   

 

 

从一大早写到现在了,午觉也没睡,写不动了,后面再来个三吧,补上:

-->7.HTML5 postMessage实现跨域

转载于:https://www.cnblogs.com/skylar/p/4101443.html

你可能感兴趣的文章
基于docker的spark-hadoop分布式集群之一: 环境搭建
查看>>
oracle 几个时间函数探究
查看>>
第一个Java Web程序
查看>>
Atomic
查看>>
div 显示滚动条与div显示隐藏的CSS代码
查看>>
Redis-1-安装
查看>>
Access denied for user ''@'localhost' to database 'mysql'
查看>>
部署支持 https 的 Nginx 服务
查看>>
WebAssembly是什么?
查看>>
树状数组_一维
查看>>
如果没有按照正常的先装iis后装.net的顺序,可以使用此命令重新注册一下:
查看>>
linux install ftp server
查看>>
嵌入式软件设计第8次实验报告
查看>>
算法和数据结构(三)
查看>>
在iOS 8中使用UIAlertController
查看>>
Ubuntu下的eclipse安装subclipse遇到没有javahl的问题...(2天解决了)
查看>>
Atcoder Grand Contest 004 题解
查看>>
alter database databasename set single_user with rollback IMMEDIATE 不成功问题
查看>>
idea 系列破解
查看>>
Repeater + Resources 列表 [原创][分享]
查看>>