一、什么是同源
源=协议+域名+端口号
如果两个url的协议、域名、端口号完全一致,那么这两个url就是同源
举例:
qq.com 、www.baidu.com 不同源
baidu.com 、www.baidu.com 不同源
- 完全一致才算同源
同源策略怎么做?
只要在浏览器里打开页面,就默认遵守同源策略。
优点
保证用户的隐私安全和数据安全。
缺点
很多时候,前端需要访问另一个域名的后端接口,会被浏览器阻止其获取响应。
比如:甲站点通过 AJAX 访问乙站点的 /money 查询余额接口,请求会发出,但是响应会被浏览器屏蔽。
二、什么是跨域
跨域:跨域名的访问,以下情况都属于跨域:
- 域名不同 www.jd.com 与 www.taobao.com
- 域名相同,端口不同 www.jd.com:8080 与 www.jd.com:8081
- 二级域名不同 item.jd.com 与 miaosha.jd.com
- 如果域名和端口都相同,但是请求路径不同,不属于跨域,如:
www.jd.com/item和www.jd… - 跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。
三、JSONP 跨域
JSONP (JSON with Padding)是一个简单高效的跨域方式,html中的script标签可以加载并执行其他域的JavaScript,于是我们可以通过script标记来动态加载其他域的资源。
例如:
frank.com访问qq.com
- qq.com 将数据写到/frends.js
- frank.com 用script标签引用/frends.js
- /frends.js执行(执行frank.com事先定义好的
window['{{xxx}}']( {{data}} )函数) - 然后frank.com就能通过window.xxx获取到数据了
a. 甲站点利用 script 标签可以跨域的特性,向乙站点发送 get 请求。
b. 乙站点后端改造 JS 文件的内容,将数据传进回调函数。
c. 甲站点通过回调函数拿到乙站点的数据。
- JSONP易于实现,但是也会存在一些安全隐患,如果第三方的脚本随意地执行,那么它就可以篡改页面内容,截获敏感数据。但是在受信任的双方传递数据,JSONP是非常合适的选择。
四、CORS 跨域
它的全称叫做Cross-Origin Resource Sharing,也就是跨域资源共享的意思,它是一种W3C规范,允许从浏览器的跨域通信。通过建立XMLHttpRequest对象的header,CORS允许开发者使用相同的习惯作为跨域请求工作。
- CORS跨域分为简单请求和复杂请求
-
简单请求
对于简单请求,浏览器直接发出CORS请求。具体来说,就是在乙站点响应头之中,增加Access-Control-Allow-Origin: http://甲站点。
例如:
qq.com在响应头里写frank.com,可以使frank.com访问qq.com的数据response.setHeader("Access-Control-Allow-Origin", "http://frank.com") -
复杂请求(非简单请求)
- 非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者
Content-Type字段的类型是application/json。 - 非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
- 浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的
XMLHttpRequest请求,否则就报错。
- 响应 OPTIONS 请求,在响应中添加如下的响应头:
Access-Control-Allow-Origin: https://甲站点 Access-Control-Allow-Methods: POST, GET, OPTIONS, PATCH Access-Control-Allow-Headers: Content-Type - 响应 POST 请求,在响应中添加
Access-Control-Allow-Origin头。
- 如果需要附带身份信息,JS 中需要在 AJAX 里设置
xhr.withCredentials = true。