和跨域CORS有关的几个请求头和响应头以及预检请求

CORS流程图

关于预检请求:

我们经常看到请求里偶尔会带着一个OPTIONS请求,这并不是我们人工添加的,为什么会出现呢? 原来在CORS跨域资源共享时,如果这次请求符合预检请求触发条件,就会被认为请求有一定风险,服务器它就不敢主动帮我们接受请求了,就需要由我们指定这次跨域请求哪些安全哪些不安全,所以会比普通cors请求多一步,需要提前通过OPTIONS方法的预检请求,和服务器确认我们的请求符合不符合条件:

大概看下,OPTIONS预检请求里就这几个请求头和响应头:

请求头:

  1. Origin:当前请求源,和响应头里的Access-Control-Allow-Origin 对标, 是否允许当前源访问,Origin是不可修改的
  2. Access-Control-Request-Headers:本次真实请求的额外请求头,和响应头里的Access-Control-Allow-Headers对标,是否允许真实请求的请求头
  3. Access-Control-Request-Method:本次真实请求的额外方法,和响应头里的Access-Control-Allow-Methods对标,是否允许真实请求使用的请求方法

响应头

  1. Access-Control-Allow-Credentials
    这里的Credentials(凭证)其意包括:Cookie ,授权标头或 TLS 客户端证书,默认CORS请求是不带Cookies的,这与JSONP不同,JSONP每次请求都携带Cookies的,当然跨域允许带Cookies会导致CSRF漏洞。如果非要跨域传递Cookies,web端需要给ajax设置withCredentials为true,同时,服务器也必须使用Access-Control-Allow-Credentials头响应。此响应头true意味着服务器允许cookies(或其他用户凭据)包含在跨域请求中。另外,简单的GET请求是不预检的,即使请求的时候设置widthCrenditialstrue,如果响应头不带Access-Control-Allow-Credentials,则会导致整个响应资源被浏览器忽略。
  2. Access-Control-Allow-Headers
  3. Access-Control-Allow-Methods
  4. Access-Control-Allow-Origin
  5. Access-Control-Expose-Headers
    在CORS中,默认的,只允许客户端读取下面六个响应头(在axios响应对象的headers里能看到):
    Cache-Control
    Content-Language
    Content-Type
    Expires
    Last-Modified
    Pragma
    
    如果这六个以外的响应头要是想让客户端读取到,就需要设置Access-Control-Expose-Headers这个为响应头名了,比如Access-Control-Expose-Headers: Token
  6. Access-Control-Max-Age:设置预检请求的有效时长,就是服务器允许的请求方法和请求头做个缓存。

关于预检请求触发特性我的一些测试:

  1. 两个一模一样的CORS请求,两个都会先发送OPTIONS预检请求:在这里插入图片描述
  2. 即使设置了Access-Control-Max-Age,并且在时间范围内服务器修改CORS响应头,浏览器也会按照新的CORS响应头处理请求

预检请求的触发条件

  • 不是GETHEADPOST其中之一;
  • 下面所列请求头以外的请求头(额外请求头)
    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
    
发布了48 篇原创文章 · 获赞 5 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章