[TOC]

1. 同源是什么

同源的源指的是什么?

源 = 协议 + 域名 + 端口号

同源的意思就是指两个 url 的源相同,即 协议、域名、端口号 完全一致,就称这两个 url 是同源的。

所以 https://www.baidu.com/https://baidu.com/ 是两个不同的源。

同源策略是浏览器设计出来用于保护用户隐私的功能,浏览器规定如果 JS 运行在源 A 里,则其就只能获取源 A 的数据,不能获取源 B 的数据,即不允许跨域。即不同源的页面之间不允许互相访问数据。

比如一个钓鱼网站知道某一用户的账号密码,然后通过 JSqq 网站的服务器发送请求,请求得到该用户的好友列表数据信息,qq 的服务器根据同源策略发现发送该请求的 url 不是同源的,就会拒绝请求。

PS:其实,在服务器端可以通过请求requestrefer属性来查看并对发送请求的 url 做出检查,但是为了安全起见,浏览器还是选择主动预防这种偷数据的行为,设置了同源策略功能。

refer.JPG

同源策略限制的是数据访问,不限制引用

2. 跨域是什么

跨域就是指想方法使得不同源的两个url间能相互访问数据,为什么会用到跨域呢?比如说源A和源B都是一个公司的,有些数据需要共享,那么就涉及到跨域操作,那么如何跨域呢?

跨域的操作有很多,以下介绍 CORSJSONP 两种方法:

2.1 CORS

CORS 全称为Cross-origin resource sharing,即跨域资源共享。

跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

CORS具体分为简单请求和复杂请求(预检请求),详细请看 mdn cors

设置CORS只需要在服务器端在回复请求的响应头里添加一句话即可,如下:

response.setHeader('Access-Control-Allow-Origin','http://foo.example')
//允许来自http://foo.example源的请求

response.setHeader('Access-Control-Allow-Origin','*')
//* 表明,该资源可以被任意外域访问

则会在允许访问的源请求得到的响应头里看到CORS,如:

example.png

使用CORS可以实现跨域,但是IE 6、7、8、9都不支持CORS。

2.2 JSONP

由上述知CORS跨域方式,IE6、7、8、9都不支持,但是JSONP跨域方式可以解决CORS的不足。

JSONP全称为JSON with Padding,和JSON本身其实没有什么关系,是用来解决跨域问题的一种方式。

浏览器设置的同源策略只是限制了数据的访问,但是对数据的引用还是可以的,例如我们在引入jQuery时使用的cdn引入,获得的jQuery.js也是来自其他源,但是我们为什么可以用呢?那是因为我们只是引用使用接口,可以直接使用,但是无法查看该文件的具体数据内容。

因此JSONP就是根据JS可以被其他源引用的原则设计的方法,具体操作为,例如源A想要源B能访问其数据,则源A在其服务器端,将要分享的数据写到一个js文件的一个全局函数xxx中,即window.xxx挂在window上的全局变量,然后源B用