Monthly Archives: 四月 2018

关于跨域 – options请求

 

跨域请求在使用POST方法向服务器发送数据时,如果Content-Type使用application/x-www-form-urlencoded、multipart/form-data或text/plain之外编码格式会由普通请求变为Preflighted请求。另外使用自定头时也会变为Preflighted请求。

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

当HTTP请求出现以下两种情况时,浏览器认为是简单跨域请求:

  1. 请求方法是GET、HEAD或者POST,并且当请求方法是POST时,Content-Type必须是application/x-www-form-urlencoded, multipart/form-data或着text/plain中的一个值。
  2. 请求中没有自定义HTTP头部。

对于简单跨域请求,浏览器要做的就是在HTTP请求中添加Origin Header,将JavaScript脚本所在域填充进去,向其他域的服务器请求资源。服务器端收到一个简单跨域请求后,根据资源权限配置,在响应头中添加Access-Control-Allow-Origin Header。浏览器收到响应后,查看Access-Control-Allow-Origin Header,如果当前域已经得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。

以下是CORS协议规定的HTTP头,用来进行浏览器发起跨域资源请求时进行协商:

  1. Origin。HTTP请求头,任何涉及CORS的请求都必需携带。
  2. Access-Control-Request-Method。HTTP请求头,在带预检(Preflighted)的跨域请求中用来表示真实请求的方法。
  3. Access-Control-Request-Headers。HTTP请求头,在带预检(Preflighted)的跨域请求中用来表示真实请求的自定义Header列表。
  4. Access-Control-Allow-Origin。HTTP响应头,指定服务器端允许进行跨域资源访问的来源域。可以用通配符*表示允许任何域的JavaScript访问资源,但是在响应一个携带身份信息(Credential)的HTTP请求时,Access-Control-Allow-Origin必需指定具体的域,不能用通配符。
  5. Access-Control-Allow-Methods。HTTP响应头,指定服务器允许进行跨域资源访问的请求方法列表,一般用在响应预检请求上。
  6. Access-Control-Allow-Headers。HTTP响应头,指定服务器允许进行跨域资源访问的请求头列表,一般用在响应预检请求上。
  7. Access-Control-Max-Age。HTTP响应头,用在响应预检请求上,表示本次预检响应的有效时间。在此时间内,浏览器都可以根据此次协商结果决定是否有必要直接发送真实请求,而无需再次发送预检请求。
  8. Access-Control-Allow-Credentials。HTTP响应头,凡是浏览器请求中携带了身份信息,而响应头中没有返回Access-Control-Allow-Credentials: true的,浏览器都会忽略此次响应。

所以服务端推荐设置: