关于javascript:一文说尽CORS

38次阅读

共计 2173 个字符,预计需要花费 6 分钟才能阅读完成。

CORS 的英文全称是 ”Cross-Origin Resource Sharing”。代表“跨域资源共享”,是一种用于在 Web 浏览器和 Web 服务器之间共享跨域资源的机制。跨域资源是指来自不同域的网页上的资源,如字体,图像,脚本和样式表等。CORS 容许网站服务器提供一组规定,以确定哪些网站能够拜访其资源。

1. 什么是跨域申请

跨域申请是指从一个 Web 页面收回的申请,而且其指标资源与以后页面不同源。
同源是指协定、域名和端口号都雷同,而不仅仅是域名雷同。
如果应用的协定、端口或域名有一个不同,它们就被视为不同源,默认不能够进行跨域拜访。

2. 预检(Preflight)申请

顾名思义,预检申请用来查看理论申请是否平安可行,确保接下来的理论申请不会引起平安问题。
浏览器会在发送预检申请之后期待响应,只有当服务器容许时,才会发送理论申请。

2.1 什么状况下会触发预检申请

预检申请的反义词是简略申请,咱们能够看下简略申请的判断规范
若申请满足所有下述条件,则该申请是简略申请:

申请办法应用下列办法之一:

  • GET
  • HEAD
  • POST

容许手动设置的标头字段为:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type(须要留神额定的限度)
  • Range(只容许简略的范畴标头值 如 bytes=256- 或 bytes=127-255)

Content-Type 标头的值仅限于下列三者之一:

  • text/plain
  • multipart/form-data
  • application/x-www-form-urlencoded

XMLHttpRequest.upload 对象属性上没有注册任何事件监听器
也就是说,没有调用 xhr.upload.addEventListener(),以监听上传申请。

申请中没有应用 ReadableStream 对象。

如果不满足上述任何一个条件,都会触发预检申请

2.2 预检申请的 CORS 解决

在 CORS 中,预检申请的目标是用于查看跨域申请是否平安、可行。
预检申请是在正式的跨域申请之前发动的一次探测,用于告知服务器,理论发送的跨域申请是否非法。
因而,对于预检申请的解决,须要服务器端进行相应的配置。
预检申请的解决步骤如下:

  • 浏览器会先发送一个 OPTIONS 申请(预检申请),蕴含了理论发送的跨域申请所须要的一些头信息,比方申请办法、申请头等。
  • 服务器收到后,会依据申请头中的信息进行判断,判断跨域申请是否平安可行。
  • 如果跨域申请非法,服务器会返回带有特定 CORS 响应头的响应,告知浏览器理论发送的跨域申请是非法的。
  • 浏览器接管到服务器的响应后,会查看响应头中的 ”CORS” 信息。如果 CORS 响应头非法,则浏览器会发送理论的跨域申请,否则会抛出跨域谬误,申请无奈胜利。

2.3 非预检申请的 CORS 解决

对于非预检申请,CORS 会依照以下规定进行解决:

  • 如果响应头中没有蕴含 ”Access-Control-Allow-Origin”,或者它的值不蕴含以后域名,则浏览器会抛出一个跨域谬误,申请无奈胜利。
  • 如果响应头中蕴含 ”Access-Control-Expose-Headers”,则该响应头中列出的头信息能够被前端 JavaScript 拜访。否则,这些头信息将被浏览器拦挡,无奈被前端 JavaScript 拜访。
  • 须要留神的是,尽管非预检申请不须要发送 OPTIONS 申请,但依然须要服务器返回非法的 CORS 响应头信息。

3. 跨域无关的响应头

上面列出了和跨域无关的响应头:

  • Access-Control-Allow-Origin:哪些源能够拜访该资源。”*” 示意所有的源都能够拜访该资源。
  • Access-Control-Allow-Credentials:是否容许发送 Cookie。
  • Access-Control-Expose-Headers:哪些响应头能够被前端 JavaScript 拜访。默认状况下,不容许拜访
  • Access-Control-Allow-Methods:哪些 HTTP 申请办法容许跨域拜访。默认状况下,只容许 GET、HEAD、POST 办法。
  • Access-Control-Allow-Headers:容许的申请头信息。默认状况下,只容许常见的申请头,Accept、Accept-Language、Content-Language、Content-Type。
  • Access-Control-Max-Age:预检申请的有效期,单位为秒。有效期内,浏览器无需再次发送预检申请。

4. 跨域和 cookie

如果须要在跨域申请中携带 Cookie,服务器须要设置响应头 ”Access-Control-Allow-Credentials” 为 true
同时前端须要设置申请头 ”withCredentials” 为 true,否则无奈携带 Cookie。

4.1 携带 cookie 时的限度

在跨域申请中携带 Cookie 时,浏览器会先发送 OPTIONS 预检申请,以查看是否容许跨域申请。
与不携带 Cookie 的状况相比,携带 Cookie 时 ”Access-Control-Allow-Origin” 字段的限度更加严格:

  • 字段不能为通配符 *,否则浏览器会疏忽 ”Access-Control-Allow-Credentials” 字段的值,不会发送 Cookie。
  • 字段的值必须与申请头中 ”Origin” 字段的值完全相同。
正文完
 0