同源策略和跨域解决方法

第一部分:同源策略: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两者可以实现跨域通信

 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中几种常见的跨域方法原理详解

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏建站达人秀

如何搭建 OpenLiteSpeed 面板

OpenLiteSpeed 是 LiteSpeed Technologies 开发的开源HTTP服务器。OpenLiteSpeed 具有高性能和轻量级的特点,并...

72310
来自专栏PHP在线

[技巧]丰富的phpstorm编辑器配色方法

1 打开编辑器 phpstorm菜单找到preferences,MAC快捷键[command+,],Editor->Colors&font->font 在此处设...

39450
来自专栏Crossin的编程教室

Python 与 Excel 不得不说的事

数据处理是 Python 的一大应用场景,而 Excel 则是最流行的数据处理软件。因此用 Python 进行数据相关的工作时,难免要和 Excel 打交道。 ...

38960
来自专栏前端说吧

Compass(更新中。。。)

26560
来自专栏一个会写诗的程序员的博客

webpack 极简教程(前端自动化构建)

Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。

12110
来自专栏Seebug漏洞平台

Bypass unsafe-inline mode CSP

[+] Author: evi1m0 [+] Team: n0tr00t security team [+] From: http://www.n0tr0...

36040
来自专栏老马寒门IT

Node入门教程(7)第五章:node 模块化(下) npm与yarn详解

Node的包管理器 JavaScript缺少包结构的定义,而CommonJS定义了一系列的规范。而NPM的出现则是为了在CommonJS规范的基础上,实现解决包...

37760
来自专栏Spark学习技巧

大数据基础系列之kafkaConsumer010+的多样demo及注意事项

一,KafkaConsumer使用要点解释 1,基本介绍 该客户端用户透明的处理kafka Broker的失败,透明的适应topic在集群中的迁移。这种客户端也...

35880
来自专栏QQ音乐技术团队的专栏

Webpack 实用技巧高效实战

在项目中使用了一段时间的 Webpack ,得益于其多元的功能支持和配置定制,得到了很多本地编译和依赖管理的帮助。在搭建好配置和架构之后,开发过程中可以不再关注...

51290
来自专栏前端知识分享

基于Vue-cli 快速搭建项目

Vue-cli可以快速帮助我们创建一个项目,这是官方给我们提供的脚手架。下面我说一下vue-cli的使用方法。

11210

扫码关注云+社区

领取腾讯云代金券