CORS解决跨域问题

  • 跨域
  • CORS
  • 简单请求
  • 预检请求
  • 认证请求
  • 服务端


跨域

当一个资源向与本身所在服务器不同的域或者端口发起请求时,会发起一个跨域HTTP请求。

CORS

CORS全称Cross-Origin Resource Sharing,也就是我们常说的跨域资源共享,CORS是通过新增一组HTTP头部字段,允许服务器声明那些源站有权限访问哪些资源。

CORS的标准规范要求可能对服务器数据产生副作用的HTTP请求方法,浏览器必须首先使用OPTIONS方法发起预检请求,如果服务器允许该跨域请求后,才可以发起HTTP请求。再预检请求的返回中,服务器可以要求客户端携带身份凭证信息。

简单请求

简单请求,顾名思义是相对简单的请求,满足一下条件的请求被称为简单请求。

  • 请求方法
  • GET
  • POST
  • HEATD
  • 字段
  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type
  • Content-Type 的值
  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded
    这些跨域请求和其他跨域请求没有区别,如果服务器没有返回正确的相应头,请求方不会收到任何数据,因此,那些不允许跨域请求的网站无需为这一新的HTTP控制特效担心。

预检请求

预检请求要求必须首先使用 OPTONS 方法发起一个预检请求到服务器,以获取服务器是否允许该实际请求。同样的他也需要满足一定的要求:

  • 请求方法
  • PUT
  • DELETE
  • CONNECT
  • OPTIONS
  • TRACE
  • PATH
  • 首部字段
  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type
  • Content-Type 的值
  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

预检请求可以避免跨域请求对服务器的用户数据产生未预期的影响。

认证请求

XMLHttpRequest 与 CORS 的一个有趣的特性是,可以基于 HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨域 XMLHttpRequest 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。

xmlHttpRequest.withCredentials = true

withCredentials 标志设置为 true,从而向服务器发送 Cookies。因为这是一个简单 GET 请求,所以浏览器不会对其发起 “预检请求”。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。

服务端

只在客户端下足功夫也不一定可以解决跨域问题,我们也需要在服务端上设置Access-Control-Allow-Origin响应头,当然我们也可以设置如Access-Control-Allow- Methods,Access-Control-Allow-Headers来告诉客户端同不同意他的请求。