资讯专栏INFORMATION COLUMN

常用跨域方法总结

jerryloveemily / 1340人阅读

摘要:常用跨域方法总结为什么要跨域因为浏览器的一种安全机制同源策略的限制,导致不能直接获取不同源的资源,所以要跨域。那么什么才叫同源呢协议相同域名相同端口号相同图来自参见最后下面介绍常用的几种跨域方法。

常用跨域方法总结 为什么要跨域?

因为浏览器的一种安全机制——同源策略的限制,导致不能直接获取不同源的资源,所以要跨域。

同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

限制之一是不能通过ajax的方法去请求不同源中的文档。
第二个限制是浏览器中不同域的框架(iframe)之间是不能进行js的交互操作的。

那么什么才叫“同源”呢?

协议相同

域名相同

端口号相同

图来自MDN,参见最后Reference.

下面介绍常用的几种跨域方法。

jsonp 跨域

原理:

利用了

如上,定义了一个全局的callback 函数,然后利用

发现什么了吗?响应内容callback("我今天要用jsonp来跨域获取数据")会被当作js代码来执行,正好调用了我们之前定义的callback函数。
由此,我们成功的利用jsonp通过跨域获取到了想要的数据。

document.domain跨域(子域名不同的框架之间)

开头我们说到不同源的框架之间是不能进行js交互操作的,其实是可以获取window对象,但不能获取window的属性。
原理:

document.domain的值是可以设置的,但仅限于设置为自身或是更高一级的父级域名(主域名相同)。

那么主域名相同,子域名不同的框架之间跨域获取数据的思路就来了,我们把它们的document.domain都设置成主域名不就完事了?
比如有一个页面a.google.com/1.html
这里参考了其他文章的代码。出处见本文最下方


另一个页面b.google.com/2.html只需设置主域名为google.com,两个框架间就可以进行交互啦。

location.hash跨域(不同源的框架之间)

原理:

hash字段(经常用于锚点定位)不属于http协议的部分,请求不会携带hash信息,所以改变不会重新请求资源(但是会产生新的浏览器历史记录,许多前端路由也是借用这个原理实现的)

父窗口可以对iframe进行URL读写,iframe也可以读写父窗口的URL(不同源的话,IE、Chrome不允许修改parent.location.hash的值,但我们仍有处理方式)

思路:

如果是父窗口向子窗口跨域传递数据,直接修改子窗口url的hash就可以了,比较简单这里就不贴代码了。

子窗口向父亲窗口跨域传递数据就需要多加一个代理窗口(因为IE,Chrome),这个代理窗口和父亲窗口同源就可以了,在这个代理窗口改变父亲窗口的hash,父亲窗口监听hashchange就可以了。

代码如下:
父亲窗口页面
http://localhost:63342/test-field/cross-origin/local-test/hash-parent.html




    
    Title





子窗口页面
http://blank121.github.io/tes...

try{
  parent.location.hash="今天我要用hash跨域"
  //chrome ie 直接修改parent.location.hash报错
}catch (e){
  var iframe = document.createElement("iframe")
  iframe.src = "https://localhost:63342/test-field/cross-origin/local-test/hash-proxy.html"+"#今天我要用hash跨域"
  document.body.appendChild(iframe);
}

代理窗口页面
http://localhost:63342/test-field/cross-origin/local-test/hash-proxy.html




    
    Title




如上,在子窗口页面内修改了代理窗口的hash值,代理窗口又修改了父亲窗口的hash值,父亲窗口监听hashchange就可以获取到不同源的子窗口传来的数据啦。
控制台结果如下:

window.name跨域(不同源框架间)

原理:

window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

利用一个窗口的生命周期内,载入不同页面window.name不变的特性
贴代码前首先去做个有趣的实验
在必应的首页设置一下window.name

然后输入location.href = "http://www.baidu.com",跳转到百度后再看一下name

666,window.name果然没骗我,没有变化。

接下来先贴代码
父亲窗口:
http://localhost:63342/test-field/cross-origin/local-test/name-parent.html




    
    Title





子窗口:
https://blank121.github.io/te...




    
    window.name跨域




代理窗口(啥也没做。主要是要和父亲窗口同源来传递name)




    
    Title



代码如上,主要思路就是利用window.name不变性,子窗口设置了name之后,来加载一个和父亲窗口同源的代理窗口,以此来获取name(注意子窗口和代理窗口是同一个iframe,加载不同页面而已,所以window.name不变)

postMessage跨域

首先了解一下postMessage
otherWindow.postMessage(message, targetOrigin);
otherWindow:指目标窗口,也就是给哪个window发消息,是 window.frames 属性的成员或者由 window.open 方法创建的窗口
message: 是要发送的消息,类型为 String、Object (IE8、9 不支持)
targetOrigin: 是限定消息接收范围,不限制请使用 *

postMessage是HTML5新特性,跨域简直太方便了,就是兼容性要注意一下。

发送方页面




    
    Title





接收方页面




    
    Title




接收方监听一下message事件,就可以接收到信息啦。

WebSocket跨域
WebSocket 是一种在客户端与服务器之间保持TCP长连接的网络协议,这样它们就可以随时进行信息交换(双工通讯)。
虽然任何客户端或服务器上的应用都可以使用WebSocket,但原则上还是指浏览器与服务器之间使用。通过WebSocket,服务器可以直接向客户端发送数据,而无须客户端周期性的请求服务器,以动态更新数据内容。

WebSocket 非常强大,笔者在这方面也是小白级别的,以后有时间会详细研究学习。

跨域代码如下
页面:




    
    Title




服务端nodeJs代码:

var WebSocketServer = require("ws").Server;
var wss = new WebSocketServer({ port: 8080 });

wss.on("connection", function connection(ws) {
  ws.on("message", function incoming(message) {
    console.log("received: %s", message);
     ws.send("hello"+message);
  });
});

结果如图:
浏览器端:

服务端:

完美实现了跨域。

CORS(cross origin resource sharing 最常用)

老生常谈的CORS,优秀的文章已经非常多了,大家可以搜一下,非常重要,有机会我会专门写一篇文章来学习总结,在此就不再详述了

最后

不得不说,这些方法还是比较巧妙的,在此写下一篇文章来总结一下,感觉自己面对跨域丝毫不慌啦。

Reference

前端跨域整理
正确面对跨域,别慌
浏览器的同源策略

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/95698.html

相关文章

  • 常用跨域方法总结

    摘要:常用跨域方法总结为什么要跨域因为浏览器的一种安全机制同源策略的限制,导致不能直接获取不同源的资源,所以要跨域。那么什么才叫同源呢协议相同域名相同端口号相同图来自参见最后下面介绍常用的几种跨域方法。 常用跨域方法总结 为什么要跨域? 因为浏览器的一种安全机制——同源策略的限制,导致不能直接获取不同源的资源,所以要跨域。 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行...

    Seay 评论0 收藏0
  • 常用跨域方法总结(2)——CORS

    摘要:常用跨域方法总结上篇文章介绍了几种常用的跨域方法常用跨域方法总结,本片为上一篇的补充,对比较重要的详细介绍。出于安全原因,从脚本内发起的跨源请求会受到一定限制。当开发者使用对象发起跨域请求时,它们已经被设置就绪。 常用跨域方法总结(2)——CORS 上篇文章介绍了几种常用的跨域方法:常用跨域方法总结,本片为上一篇的补充,对比较重要的Cross Origin Resource Shari...

    Jason_Geng 评论0 收藏0
  • 常用跨域方法总结(2)——CORS

    摘要:常用跨域方法总结上篇文章介绍了几种常用的跨域方法常用跨域方法总结,本片为上一篇的补充,对比较重要的详细介绍。出于安全原因,从脚本内发起的跨源请求会受到一定限制。当开发者使用对象发起跨域请求时,它们已经被设置就绪。 常用跨域方法总结(2)——CORS 上篇文章介绍了几种常用的跨域方法:常用跨域方法总结,本片为上一篇的补充,对比较重要的Cross Origin Resource Shari...

    ZoomQuiet 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<