浏览器的同源策略机制以及跨域请求

同源策略机制

同源策略机制(Same Origin Policy,SOP)是一种约定,它是浏览器最核心也是最基本的安全功能,如果缺少了同源策略。则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础上的,浏览器只是针对同源策略的一种实现。

当一个浏览器的两个tab页中分别打开百度和谷歌的页面时,当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。 如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以google.com下的js脚本采用ajax读取baidu.com里面的文件数据是会报错的。

跨域请求,首先浏览器为了安全,做了一个同源策略机制,也就是所谓的同源安全策略,本质上,其实是不存在所谓的跨不跨域的,把浏览器想象成一个发送网络请求的软件,按照道理来说,请求都是可以发送出去的,但是在 web 端,浏览器里,这么做的就不合适,如果网络上的接口可以不受限制的被任意人调用,那将是一个非常混乱的场景,所以,为了防止这种情况,浏览器做了这个同源策略来防止这种情况发生。

在这里插入图片描述
参考下面这个表格:
在这里插入图片描述

总结:协议相同+域名相同+端口号相同,浏览器才认为是同一个网站,才不会受到同源策略的影响,才可以正常的发送Ajax请求。对于 ,

所谓的同源策略是浏览器实现的,而和后台服务器无关,A 发送请求到 B. 请求实际上是发送到了 B 后台, B后台接受到数据后。其实也有返回,只不过,这个数据返回到浏览器之后,浏览器把这个数据给劫持了,不让A网站使用

既然跨域这么麻烦,为什么要进行跨域?

因为当一个项目变大时,把所有的内容都丢在一个网站或者是后台服务器中是不现实的.

比如:

一个网站体量很大.有很多可以独立且复杂的业务

  • 比如有一个订单管理的后台数据API网站服务.
  • 比如有一个用户管理的后台数据API网站服务.
  • 比如有一个新闻管理的后台数据API网站服务.

最后剩下的就是web的UI层面的东西,把这个UI层面的东西和哪个数据服务API的网站集成在一起比较合适呢?

都不适合,它应该是一个专门的网站.
在这里插入图片描述

实现跨域请求的几种方法

(1)利用jsonp进行跨域

jsonp 跨域是里用在浏览器中,下载一个script标签是不受同源策略限制的特性.

具体实现原理大概分下面几步

  • 客户端动态的创建一个 script 标签
  • 设置 script 标签的src 为跨域的服务器后台.
  • src 中需要带一个 callback 查询字符串,告诉后台,前端提供的方法名是什么.
  • 然后后端,直接返回一一串 callback(data) 的字符串给浏览器即可.

jsonp使用总结:

  • 利用 script 标签异步加载,而非传统的ajax
  • 异步 script 加载不受浏览器同源策略限制.
  • 给script.src=callback=fn来告知请求的后台前端提供的fn是什么
  • 基本就是前端提供方法,后端提供数据并调用前端的这个方法.
  • jsonp 只支持 get 请求.(本质上,不就是下载文件吗?下载文件一般都是get请求)

(2)利用cors进行跨域请求

cors 是 Cross-Origin-Resource-Sharing 的缩写,也是现代浏览器普遍支持的一种非常方便的跨域方案.

它的具体工作流程是:

浏览器在检测到你发送的 ajax 请求不是同源请求时,会自动在 http 的头部添加一个 origin 字段.

在这里插入图片描述
我们拿不到数据是因为浏览器在中间做了一层劫持。

在这里插入图片描述
在这里插入图片描述

跨域获取不到数据的原因很简单:

  • 这是一次跨域请求
  • 请求确实发送到服务器了
  • 服务器也确实把数据返回到了浏览器
  • 但是服务器返回的响应头里面,没有告诉浏览器哪个域名可以访问这些数据,(也就是没有设置Access-Control-Allow-Origin)
  • 于是浏览器就把这个数据丢弃了,我们也就无法获取到这个数据。

这个时候,只需要后台在相应头里加上一个 Access-Control-Allow-Origin:* 即可完成跨域数据获取.

在这里插入图片描述
CORS 跨域方案简单总结:

  • 当浏览器发送一个请求是跨域的时候,会自动加上Origin
  • 需要后台配合设置响应头Access-Control-Allow-Origin:*|Origin即可完成跨域.
  • CORS支持GET,POST常规请求
  • 同时也支持PUT,DELETE等非post,get的请求,但会先发出一次预检请求。
    在这里插入图片描述

(3)proxy代理模式进行跨域

核心思想:让前端请求我们自己的后台,让后台去请求另一个后台,(因为后台和后台之间不用跨域,也没有同源策略机制,)获取真实的数据,然后把数据返回给前台,实现方式可以利用nginx做反向代理,以及我们写一个后台中转的服务器。
这个proxy代理跨域是后端的实现,目前我只掌握了它的原理思路。具体的操作还没学会。


版权声明:本文为weixin_45447369原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。