浏览器跨域请求中options的问题处理

跨域请求中的options请求,在以往的项目中有注意到,但是今天因为一个问题,卡了2小时才解决,这么久的时间足以说明我对这个问题并没有充分的理解和认识,为此写下这篇文章警示自己,同时也给碰到问题的同学提供一些思路。

跨域请求的三种方式

XHR对象对于HTTP跨域请求有以下三种方式

  • 简单请求
  • Preflighted 请求
  • Preflighted 认证请求

1、简单请求

简单请求进行跨域访问时,XMLHttpRequest对象会直接将实际请求发送给服务器,和一般请求没有差别。但是,要达成简单请求,请求中必须满足下面的所有要求

  • 以下请求方法之一
    • GET
    • HEAD
    • POST
  • 不可使用自定义的请求头字段,除了以下被规定的字段
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type
    • DPR
    • Downlink
    • Save-Data
    • Viewport-Width
    • Width
  • Content-Type 的值仅限于下列三者之一:
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

2、Preflighted 请求

Preflighted 请求与简单请求不同,Preflighted 请求首先会向服务器发送一个Options请求,以验证是否对指定服务有访问权限,之后再发送实际的请求。Preflighted 请求具有以下特点:

  • 除GET、HEAD、POST方法外,XHR都会使用Preflighted 请求,Content-Type和上一个不一样时也会触发Preflight请求,比如现在常用的application/json格式。
  • 使用了自定义的HTTP Headers后,也会使用Preflighted 请求。

3、Preflighted 认证请求

XMLHttpRequest可以在跨域请求时发送认证信息,但在默认情况下HTTP Cookies和HTTP 认证是不被发送的。要发送Preflighted 认证请求需要设置XMLHttpRequest对象的withCredentials属性为true,在jquery的ajax和axios中,都有该选项,如果请求需要带上cookie验证信息,记得声明为true。
如果服务器响应头没有Access-Control-Allow-Credentials: true,浏览器也会拒绝。
认证请求不同于其它请求的一点,要求明确响应Access-Control-Allow-Origin头,要明确指定要响应的站点,Access-Control-Allow-Origin: *的响应方式在认证请求中是不合法的。

最后

我们也不用非要避免预检请求,但是有时候后端配置问题或者运维配置问题,会导致一些配置不生效,所以前端做一些处理还是有必要的,最后写下后端放开跨域的处理代码
补充:后端对options接口一定要返回2xx(成功)状态码,这样才会触发真实请求

response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE");
response.setHeader(“Access-Control-Allow-Headers”, “x-requested-with,Authorization,Content-Type”)

本文参考

  1. axios请求接口发起两次请求(OPTIONS 与POST/GET)
  2. 为什么XMLHttpRequest的POST请求会变OPTIONS请求-XMLHttpRequest对象对HTTP请求的访问控制(CORS跨站资源共享)

你可能感兴趣的:(前端,前端,HTTP,跨域)