前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >同源策略和跨域解决方法

同源策略和跨域解决方法

作者头像
用户1149564
发布2018-01-11 17:47:03
1.9K0
发布2018-01-11 17:47:03
举报
文章被收录于专栏:Micro_awake web

第一部分:同源策略:same-origin policy

1.同源策略的由来:

1995年,同源策略由Netscape(曾经的浏览器霸主,拒绝微软收购请求,被IE给整垮。现在发展为火狐浏览器背后的Mozilla)引入。目前,所有浏览器都遵循同源策略

2.同源定义:即同协议、同域名、同端口号

例如:http://www.test.com:80/test.html;     协议:http;域名:www.test.com;端口号:80(默认端口,可以省略)

http://www.test.com/test100.html    (同源) http://test.com/test100.html      (不同源,域名不同) http://x.www.test.com/test100.html  (不同源,域名不同) http://www.test.com:81/test100.html  (不同源,端口号不同) https://www.test.com/test100.html  (不同源,协议不同)

但是在IE浏览器上端口号不同被认为是同源

截图自MDN,链接

3.同源策略目的:

防止其它网站恶意窃取数据。 例如: 假设没有同源策略:用户在银行网站A上访问,cookie记录了A银行存款金额、存款频率、存款频率等信息;当用户离开A网站,访问游戏网站B时,此时网站B可以读取cookie。那么用户的隐私就被泄露了! 更严重的是,cookie往往保存用户登录状态,如果用户离开A网站(但是没有退出登录),那么B网站其实是可以冒充用户进入A网站

4.非同源带来的结果:

  • cookie,localStorage和indexdDB无法读取
  • DOM无法获得
  • Ajax请求无效(请求发送后,浏览器不会进行响应)

第二部分:跨域解决方法

1.设置document.domain来跨子域:(适用于cookie、iframe)

比如http://a.test.com和http://b.test.com;

如果设置了document.domain='test.com';那么两者之间可以共享cookie(即一级域名相同,二级域名不同,可以设置document.domain来共享cookie)

同时,服务器可以在设置cookie的时候,指定一级域名,也能达到共享cookie的效果。如:Set-Cookie:key=value;domain=.test.com;path=/

iframe:也可以通过上述document.cookie设置,从而共享cookie、iframe拿到父窗口的DOM、父窗口拿到iframe的DOM。

如:父窗口是http://a.test.com,iframe是http://test.com;当设置了document.domain="test.com"时,就能进行跨域了。

2.同源域名下架设代理服务器:JavaScript将请求发送到代理服务器,代理服务器再将结果返回。

如:'/proxy?url=http://www.test.com'

不过这种显然需要配置额外服务器,开销变大。

3.使用window.name来跨域:

window.name:在不同的页面(甚至不同的域名)加载后依然存在(如果值没被修改,则不会发生变化),并且name值可达2MB(对于一般的运用完全够用)

4.片段识别符(fragment identifier)URL中#后面的部分。比如http://www.test.com#apple的#apple就是片段识别符。

改变片段识别符,页面不会重新刷新

父窗口将信息,写入子窗口片段识别符;子窗口通过监听hashchange事件得到通知

5.window.postMessage:HTML5为了解决跨域问题,引进的全新API:跨文档通信API(cross-document messaging)

父窗口:http://a.com,子窗口:http://b.com;显然两者不同源,但是通过postMessage两者可以实现跨域通信

代码语言:javascript
复制
 1 var a=window.open('http://b.com');
 2         //父窗口向子窗口发送信息hello 1
 3         a.postMessage('hello 1','http://b.com');
 4         //子窗口向父窗口发送信息hello 2
 5         window.opener.postMessage('hello 2','http://a.com');
 6 
 7         //父窗口和子窗口都能通过message事件,监听对方信息
 8         window.addEventListener('message',function(e){
 9             console.log(e.data);
10         })

6.JSONP:这个就很常见了。老式浏览器都支持,兼容性好,简单实用。(不过只支持get请求)

基本思想:网页通过添加一个<script>元素,向服务器发送JSON数据,这种方法是不受同源策略限制的;服务器收到请求后,将数据放入指定的回调函数中返回。

截图至阮一峰JavaScript标准参考教程。

添加<script>元素,向服务器发送请求,同时请求中指明了回调函数foo,服务器以回调函数的形式返回数据。

7.websocket:这个是通信协议,好比是打电话。与传统的http协议,只能客户端向服务器发送请求,服务器进行效应的原理不同。

websocket可以由客户端向服务器发送连接请求,也可以服务器向客户端发送连接请求。它们之间的连接是持续打开的数据通道,就好比是打电话!

websocket不受同源策略制约,可以用来跨域通信。将可以通信的域名放在白名单里。

8.安装flash插件,现在flash插件用的越来越少,而且复杂。不推荐!

9.CORS(跨域资源共享)cross-origin resource sharing支持所有类型的请求,对比JSONP只支持get请求

它是一个W3C标准,允许浏览器跨域发送XMLHttpResuest对象。这是Ajax跨域的终极解决方法。

目前,IE10以上,现代浏览器均支持CORS。

主要原理:浏览器发现Ajax跨域请求,就会自动添加一些头部信息;对于非简单请求,还会多出一次附加请求;但是这些用户都察觉不到。而服务器端布置了CORS接口(设置了相关数据信息如:Access-Control-Allow-Origin)

所以:CORS需要客户端与服务器同时支持!

更多详细参考:阮一峰JavaScript标准参考教程

10.可参见:PHP Ajax 跨域问题最佳解决方案

通过设置Access-Control-Allow-Origin来实现跨域。

更多参考:1.阮一峰JavaScript标准参考教程

2.Ajax廖雪峰的官方网站

3.js中几种常见的跨域方法原理详解

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-12-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档