了解跨域

172 阅读3分钟

1. 浏览器会对跨域做出哪些限制?

A和B是非同源的,那么浏览器会有如下限制:

  1. DOM访问限制:A的脚本不能读取和操作B的脚本;
  2. Cookie访问限制:A不能访问B的Cookie;
  3. Ajax响应数据限制:A可以给B发请求,但无法获取B响应的数据。 注意:在这三条中,浏览器对Ajax获取数据的限制是影响最大的一个,且实际开发中经常遇到

2. 注意点

  1. 跨域仅存在浏览器端,服务端不存在跨域限制;
  2. 即使跨域了,Ajax请求也可以正常发出,但响应数据不会交给开发者; image.png
  3. <link>, <script>,<img>......这些标签发出的请求也可能跨域,只不过浏览器对标签跨域不做严格限制,对开发几乎无影响。

3. 解决跨域

1. CORS解决Ajax跨域问题

cors:cross-origin resource sharing 跨域资源共享

用于控制浏览器校验跨域请求的一套规范,服务器依照cors规范,添加特定响应头来控制浏览器校验,大致规则如下:

  • 服务器明确表示拒绝跨域请求,或没有表示,则浏览器校验不通过;
  • 服务器明确表示允许跨域请求,则浏览器校验通过; 备注:使用cors解决跨域是最正统的方式,且要求服务器是“自己人”。

简单请求与复杂请求

cors把请求氛围两类:简单请求、复杂请求

简单请求复杂请求
请求方法(method)可以为:GET, HEAD, POST不是简单请求,就是复杂请求;复杂请求会自动发送预检请求;
请求头字段要符合《CORS安全规范》(只要不手动修改,一般不会有问题
请求头的Content-Type的值只能是以下三种:
text/plain
multiple/form-data
application/x-www-form-urlencoded
关于预检请求
  1. 发送时机:在实际跨域请求之前发出,是由浏览器自动发起的;
  2. 主要作用:用于向罗兰器确认是否允许接下来的跨域请求;
  3. 基本流程:先发起OPTIONS请求,如果通过预检,继续发起实际的跨域请求;
  4. 请求头内容:一个OPTIONS预检请求,通常包含如下请求头
请求头含义
Origin发起请求的源
Access-Control-Request-Method实际请求的HTTP方法
Access-Control-REquest-Headers实际请求者使用的自定义头(如果有的话)

CORS解决复杂请求

  1. 第一步:服务器先通过浏览器的预检请求,服务器需返回如下响应头:

image.png

image.png

  1. 第二步:处理实际的跨域请求(与处理简单请求跨域的方式相同)

image.png

借助cors库快速完成配置

上述的配置中需要自己配置响应头,或需要自己手动封装中间件,借助cors库,可以更方便地完成配置

  • 安装cors
npm i cors
  • 简单配置cors
app.use(cors())
  • 完成配置cors

image.png

2. JSONP解决跨域问题

JSONP利用了<script>标签,并将其可以跨域加载脚本,且不受严格限制的特性。 可以说是程序员智慧的结晶,早起一些浏览器不支持CORS时,可以靠JSONP解决跨域(仅支持GET请求)

基本流程:

  1. 客户端创建一个<script>标签,并将其src属性设置为包含跨域请求的URL,同时准备一个回调函数,这个回调函数将用于处理返回的数据;
  2. 服务端接收到请求后,将数据封装在回调函数中并返回;
  3. 客户端的回调函数被调用,数据以参数的形式传入回调函数;

图示:

image.png

3. 配置代理解决跨域

自己配置代理服务器

借助http-proxy-middleware配置代理

image.png

使用Nginx搭建代理服务器

借助脚手架搭建服务器