认识一下CORS(Cross-Origin Resource Sharing)

What’ CORS - Cross-Origin Resource Sharing

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin. A web application makes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, and port) than its own origin.

支持CORS请求的浏览器一旦发现ajax请求跨域,会对请求做一些特殊处理,对于已经实现CORS接口的服务端,接受请求,并做出回应。

有一种情况比较特殊,如果我们发送的跨域请求为“非简单请求”,浏览器会在发出此请求之前首先发送一个请求类型为OPTIONS的“预检请求”,验证请求源是否为服务端允许源,这些对于开发这来说是感觉不到的,由浏览器代理。

总而言之,客户端不需要对跨域请求做任何特殊处理。

CORS存在的意义

为了保证用户信息的安全,所有的浏览器都遵循同源策略。

凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同,即为跨域(不同源)

  • 域名(domain)
  • 协议(protocol)
  • 端口(porot)

同源策略的限制:

  • 无法获取非同源的Cookie、LocalStorage、SessionStorage等
  • 无法获取非同源的dom
  • 无法向非同源的服务器发送ajax请求

CORS的请求Header

  • origin:表明预检请求或实际请求的源站URL,总是会带上
  • Access-Control-Request-Method:实际请求所使用的HTTP方法告诉服务器
  • Access-Control-Request-Headers:将实际请求所携带的首部字段告诉服务器

CORS的响应Header

  • Access-Control-Allow-Origin:这个请求头一般会被服务器端返回,它的值代表了哪些域名你有权可以访问(注:对于携带身份凭证的请求不可使用通配符*)
  • Access-Control-Expose-Headers:指定XMLRequest的getResourceHeader可以访问的响应头
  • Access-Control-Max-Age:指定preflight请求的结果能够被缓存多久
  • Access-Control-Allow-Credentials:是否允许浏览器读取response的内容;
  • Access-Control-Allow-Methods:指明实际请求允许所使用的HTTP方法
  • Access-Control-Allow-Headers:指明实际请求中允许携带的首部字段

什么是简单请求?

请求方法属于以下类型:

  • HEAD
  • GET
  • POST

Headers不超出以下字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type: application/x-www-form-urlencoded、 multipart/form-data、text/plain
  • DPR
  • Downlink
  • Save-Data
  • Viewport-Width
  • Width

不满足上述要求的在发送正式请求前都要先发送一个预检请求,预检请求以OPTIONS方法发送,浏览器通过请求方法和请求头能够判断是否发送预检请求。

服务器端在处理OPTIONS请求的时候需要注意:需要预检请求时,浏览器会发出两次请求,一次OPTIONS,一次POST。两次都返回了数据。如果服务端逻辑复杂一些,比如去数据库查找数据,从web层、service到数据库这段逻辑就会走两遍,浏览器会两次拿到相同的数据。如果是OPTIONS请求,在设置完跨域请求响应头后就不走后面的逻辑直接返回。

Reference

重点阅读:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
https://zhuanlan.zhihu.com/p/29980092
https://juejin.im/post/5a7359876fb9a0634a38e389