浏览器跨域之CORS

本文为前端学习http的一部分,请结合github上的实例进行阅读能有更深的体会,Enjoy your time!

CORS

背景:为了提高安全性,浏览器添加了同源策略限制跨域访问;但与此同时降低了开发的灵活性。为此,浏览器提供了折中方法,只要遵循CORS协议,跨域也可访问。
定义:CORS全称:cross-origin resource sharing,跨域资源共享。实现方式是服务端添加若干请求头(以下详解)。

此方法有兼容性的限制,主要限制是IE11才支持CORS。

浏览器跨域之CORS_第1张图片
cors.jpg

preflighted requests

在跨域的情况下,请求被分为两种simple requests和preflighted requests,它们(的条件)是相互排斥的。
满足以下任一条件为preflighted requests:

  1. 请求的方法为:PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH
  2. 超过以下内容(又被称为"CORS-safelisted request-header")的请求头:
    Accept, Accept-Language, Content-language, Last-Event-ID, DPR, Downlink, Save-Data, Viewport-Width, Width, Content-Type(值必须为以下3个:application/x-www-form-urlencode, multipart/form-data, text/plain)
    比如说:请求头含有Content-Type: application/xml。虽然是Content-Type,但它的值不是3个可选值之一。所以这个请求为preflighted requests。

特点:在发送preflighted requests真正请求之前,会发送OPTIONS请求去验证。

options

定义:在跨域的情况下,如果请求为preflighted request,则在请求前,浏览器会自动先发送options请求,去探测是否安全,来决定是否要发送真正的请求。

例子:

var myRequest = new Request('http://0.0.0.0:41230/api', {
  credentials: 'include',
  method: 'PUT',
  headers: {
    'Content-Type': 'application/xml'
  }
})

Access-Control-Allow-Origin

定义: 服务端response headers添加这个字段,表示可以允许跨域访问。值为允许访问的来源域,也既是request的origin,比如http://bar.com,或*(表示任意来源域都可以访问)。如果使用了credentials字段,则不能用*。

例子:

app.use(function (req, res, next) {
  // res.header("Access-Control-Allow-Origin", "*"); 
  // 由于有credentials,Access-Control-Allow-Origin的值必须为某个域名
  res.header("Access-Control-Allow-Origin", "http://0.0.0.0:41239");
  res.setHeader('Access-Control-Allow-Credentials', true)

  next();
})

Access-Control-Allow-Methods

定义:在跨域的情况下,如果请求为preflighted request,则必须添加这个字段,值为允许的请求方式。

app.use(function (req, res, next) {
  res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, PUT, DELETE, TRACE, PATCH')
  next();
})

Access-Control-Allow-Headers

定义:在跨域的情况下,如果含有特殊请求头,使得请求变为preflighted request,则必须添加这个字段。值为特殊请求头。

//客户端
var myRequest = new Request('http://0.0.0.0:41230/api', {
  headers: {
    'Content-Type': 'application/json', //常规头部信息,但是值特殊,也触发了preflighted request
    'X-PINGOTHER': 'pingpong' //特殊头部信息
  }
})
//服务端
app.use(function (req, res, next) {
  res.setHeader('Access-Control-Request-Headers', 'X-PINGOTHER', 'Content-Type')
  next();
})

Access-Control-Allow-Credentials

定义:在跨域的情况下发送HTTP cookies或者HTTP Authentication information,需要client和server共同设置credentials字段才能发送成功。

// 服务端
app.use(function (req, res, next) {
  res.setHeader('Access-Control-Allow-Credentials', true)
  next();
})
//客户端
// ajax      withCredentials: true
// fetch     credentials: 'include'

参考资料

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
http://www.ruanyifeng.com/blog/2016/04/cors.html

你可能感兴趣的:(浏览器跨域之CORS)