跨域问题解决方案汇总

同源策略导致的跨域问题在开发过程中经常出现,这里总结了Ajax请求导致的跨域问题解决方法。

其中CORS是最常用也是最全面的解决方案。

前端与后端都可以解决跨域问题,主要有以下四种方法:

CORS

CORS是W3C标准,全称为跨域资源共享(Cross-origin resource sharing)

CORS是跨域问题的终极解决方案,是以官方标准的形式推出的,而其余解决方案其实都是以各种方式避开同源策略的限制。不像是JSONP必须是GET请求,使用CORS时没有任何限制,且个人感觉用起来也比较丝滑。

使用CORS的前提是需要浏览器支持,现在较新的浏览器均支持CORS,若是旧版浏览器则无法使用CORS。所以需要确认用户使用环境是支持CORS的浏览器,在此基础上后端再实现对CORS的支持。

简单请求与非简单请求

CORS请求分为两类:简单请求和非简单请求。

同时满足两个条件,即为简单请求,反之为非简单请求。

  1. 请求方法是以下方法之一
    1. GET
    2. POST
    3. HEAD
  1. HTTP的头信息不超过以下几个字段
  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

两种请求跨域时的处理方式

简单请求

浏览器会直接发送简单请求给服务器,同时在请求头上添加一个Origin字段,Origin字段说明本次请求的源(协议+域名+端口号)。

服务端收到请求后,会根据Origin字段判断是否允许这次跨域请求,若允许,则会在返回的头信息里添加一些字段

Access-Control-Allow-Origin: http://localhost:3000

Access-Control-Allow-Credentials: true

Access-Control-Expose-Headers: FooBar

  • Access-Control-Allow-Origin 字段是必有的,浏览器会根据此字段判断请求是否成功,若不包含此字段则意味着此次请求不在跨域允许范围内,浏览器会抛出CORS异常。
  • Access-Control-Allow-Credentials表示服务器是否允许发送cookie
  • Access-Control-Expose-Headers 表示返回值允许暴露的字段

非简单请求

对于非简单请求,浏览器会先发送一个没有请求体的预检请求,再发送带请求体的正式请求:

预检请求用于询问服务器,当前域名是否在服务器允许范围内,以及可以使用哪些HTTP Header字段。得到肯定回复后再发送正式请求

预检请求的方法是OPTIONS,主要包含三个关键的请求头:

  • Origin:说明请求源
  • Access-Control-Request-Method:说明之后的正式请求会用到哪个HTTP方法
  • Access-Control-Request-Headers:说明CORS请求会额外发送的请求头字段

服务器会返回包含Access-Control-Allow-Origin字段的头信息:

Access-Control-Allow-Origin: http://localhost:3000

Access-Control-Allow-Methods: GET, POST, PUT

Access-Control-Allow-Headers: X-Custom-Header

Access-Control-Allow-Credentials: true

Access-Control-Max-Age: 1728000

若没有任何CORS相关的头字段信息则表示服务端不同意预检请求,不会进行之后的正式请求

  1. Access-Control-Allow-Methods
    1. 表示服务器支持的所有跨域请求的方法,不仅仅是这一次预检的方法,这样可以避免多次预检
  1. Access-Control-Allow-Headers
    1. 表示服务器支持的所有头字段信息
  1. Access-Control-Allow-Credentials
    1. 与简单请求时一样,表示服务器是否允许发送cookie
  1. Access-Control-Max-Age
    1. 指定本次预检请求的有效期。即预检结果的缓存时间

服务端/nginx设置

  1. 服务端如何设置

对于Spring boot后端工程,只需在Controller层添加注解即可:

@CrossOrigin
  1. 现在大部分后端工程都会通过nginx进行请求转发,也可以在nginx里设置支持CORS,只需在返回头增加上述以Access-Control-Allow开头的几个字段即可。

架设代理服务器

同域名架设代理服务器,代理服务器转发请求。通过这种方式绕开同源策略的限制。

JSONP

因为同源策略不对<script>标签的src属性进行限制,可以通过此标签发送跨域的Get 请求。

WebSocket

WebSocket是一种通信协议。

浏览器对于WebSocket是不受同源策略限制的,只要服务器支持此协议的请求,就可以通过WebSocket进行跨域请求。

主要原因是因为WebSocket协议头信息包含Origin字段,服务器会根据此字段判断域名是否在白名单里,所以浏览器没有对WebSocket协议的请求进行同源策略限制。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值