zhangdizhangdi

跨域

同源策略

跨域问题其实就是浏览器的同源策略所导致的。

协议、主机、端口 都相同,即为同源。

同源策略限制内容有:

  • Cookie、LocalStorage、IndexedDB 等存储性内容
  • DOM 节点
  • AJAX 请求发送后,结果被浏览器拦截了

但是 img、link、script 标签是允许跨域加载资源

两种请求

简单请求

请求方法是以下三种之一:

  • HEAD
  • GET
  • POST

头信息仅限以下字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

非简单请求

凡是不同时满足以上条件,均属于非简单请求。

正式请求前会发一次 OPTIONS 类型的查询请求,称为 预检请求,询问服务器是否支持网页所在域名的请求,以及可以使用哪些头信息字段。只有收到肯定的答复,才会发起正式请求,否则报错。

CORS

CORS(Cross-Origin Resource Sharing),跨源资源共享

响应头

  • Access-Control-Allow-Origin
    指示响应的资源是否可以被给定的来源共享。
  • Access-Control-Allow-Credentials
    指示当请求的凭证标记为 true 时,是否可以公开对该请求响应。
  • Access-Control-Allow-Headers
    用在对预检请求的响应中,指示实际的请求中可以使用哪些 HTTP 标头。
  • Access-Control-Allow-Methods
    指定对预检请求的响应中,哪些 HTTP 方法允许访问请求的资源。
  • Access-Control-Expose-Headers
    通过列出标头的名称,指示哪些标头可以作为响应的一部分公开。
  • Access-Control-Max-Age
    指示预检请求的结果能被缓存多久。

请求头

  • Access-Control-Request-Headers
    用于发起一个预检请求,告知服务器正式请求会使用哪些 HTTP 标头。
  • Access-Control-Request-Method
    用于发起一个预检请求,告知服务器正式请求会使用哪一种 HTTP 请求方法。
  • Origin
    指示获取资源的请求是从什么源发起的。

跨域时的Cookie

CORS 请求默认不发送 Cookie 和 HTTP 认证信息。

如果要把 Cookie 发送到服务器:

  1. 要服务器同意
    • 设置 Access-Control-Allow-Credentials: true 响应头
    • 相应的使用中间件设置 credentials
  2. 客户端同意
    • xhr: withCredentials = true
    • fetch :credentials: ‘include’

如果要发送 Cookie,Access-Control-Allow-Origin 就不能设为 *,必须指定明确的、与请求网页一致的域名。同时,Cookie 依然遵循同源策略。

参考