https://ieftimov.com/post/deep-dive-cors-history-how-it-works-best-practices/

同源与非同源

同源与非同源可以从三个方面判断:

  1. 协议(http/https)
  2. 域名(www.example.com/example.com)
  3. 端口(80/443)

三者只要有一个不一样就非同源。
如:https://blog.example.com/posts/foo.html

URL Result Reason
https://blog.example.com/posts/bar.html Same Only the path differs
https://blog.example.com/contact.html Same Only the path differs
http://blog.example.com/posts/bar.html Different Different protocol
https://blog.example.com:8080/posts/bar.html Different Different port (443by default)
https://example.com/posts/bar.html Different Different host

同源策略

同源策略可以防止很多网络攻击,但是很难适应现在越来越多的重资源网页和单页面网页。
于是CORS应运而生。

CORS

CORS是一种控制加载子资源权限的机制。主要分为一下三种类型:

  1. 跨源写入cross-origin writes (cross origin post)
  2. 跨源嵌入 cross-origin embeds (<img /> <video />)
  3. 跨源读取 cross-origin reads (cross origin ajax)

跨源写入Cross-origin writes

从非同源页面发起 Ajax Post 时,会先发一个 Ajax Option ,这是 preflight request。这一般会出现在复杂的 CORS 请求中。复杂的请求符合一下三个条件之一即可。

  1. GETPOSTHEAD 方法以外的请求
  2. 请求头(headers)中含有 AcceptAccept-LanguageContent-Language 以外的内容
  3. Content-Typeapplication/x-www-form-urlencodedmultipart/form-datatext/plain 以外的值。

如果是复杂的 CORS ,这就需要在 Ajax Header 做对应的修改,如headers: {"content-type": "text/plain"}
发起 Ajax Option ,等待200返回后,再发起 Ajax Post 。但如果 Ajax Option 请求没有被正确配置,这个时候服务器会阻断这个返回,这就需要返回正确的 Ajax Option 。其中包括

  1. Access-Control-Allow-Methods:允许的请求方法(response.headers["Access-Control-Allow-Methods"] = "post"
  2. Access-Control-Allow-Headers:允许的请求头内容(response.headers["Access-Control-Allow-``Headers"] = "Content-type"
  3. Access-Control-Allow-Origin:允许的请求源(response.headers["Access-Control-Allow-``Origin"] = "https://www.google.com"

Ajax Option 配置正确后,还需要配置争取的 Ajax Post 返回,给 Ajax Post 配置正确的返回头(response.headers):Access-Control-Allow-Origin。给 Ajax Post 配置允许的请求源。
这样,一个正确的 CORS 就配置完成了。

小结:跨源写入会先写入一个Ajax Option,等待Ajax Option验证通过后才允许真正的请求。如此,就需要为Ajax Option配置正确的返回头(response.headers),从而让真正的请求可以执行,真正的请求执行时,也需要为他配置正确的返回头(response.headers)。

跨源读取

跨源读取是默认阻断的
实际上虽然请求被阻断了,但是浏览器已经正常的发送了请求并拿到了返回,只是返回被阻断了。这需要我们设置一下 Access-Control-Allow-Origin

优化CORS

优化 CORS 的方法是配置 Access-Control-Allow-Credentialsinclude