共计 1787 个字符,预计需要花费 5 分钟才能阅读完成。
01、索引
https://waterflow.link/articles/1665656761584
1、为什么跨域
跨域资源共享 (CORS) 是一种基于 HTTP 标头的机制,它容许服务器批示除其本身之外的任何起源(域、计划或端口),浏览器应容许从中加载资源。CORS 还依赖于一种机制,浏览器通过该机制向托管跨域资源的服务器收回“预检”申请,以查看服务器是否容许理论申请。在该预检中,浏览器发送批示 HTTP 办法的标头和将在理论申请中应用的标头。
跨域申请的示例:从 https://a.com 提供的前端 JavaScript 代码应用 ajax 向 https://b.com/data.json 发出请求。
出于平安起因,浏览器限度从脚本发动的跨域 HTTP 申请。例如,ajax 和 申请的 API 遵循同源策略。这意味着应用这些 API 的 Web 应用程序只能从加载应用程序的同一起源申请资源,除非来自其余起源的响应蕴含正确的 CORS 标头。
2、跨域的规定
CORS 规范通过增加新的 HTTP 头来工作,服务器能够返回容许哪些起源从 Web 浏览器读取该信息。此外,对于可能对服务器数据造成副作用的 HTTP 办法(特地是 GET 以外的 HTTP 办法,或具备某些 MIME 类型的 POST),标准要求浏览器“预检”申请(先发送 OPTIONS 申请),而后在服务器“容许”后发送理论申请。
CORS 失败会导致谬误,但出于平安起因,JavaScript 无奈取得无关谬误的详细信息。所有代码都晓得产生了谬误。确定具体出了什么问题的惟一办法是查看浏览器的控制台以获取详细信息。
3、跨域场景
1、不会触发预检
简略的申请不会触发预检,那什么是简略的申请呢?
- 首先申请办法必须是 GET、HEAD、POST 其中之一
-
除了客户端主动设置的 header 头(比方:Connection、User-Agent 等),只能设置如下的这些 header 头
- Accept
- Accept-Language
- Content-Language
- Content-Type:只容许 application/x-www-form-urlencoded、multipart/form-data、text/plain 类型
- Range:只能是一些简略的 header 头,比方 bytes=256- 或者 bytes=127-255
上面是一个简略申请的流程:
- 首先客户端会向 a.com 会向服务端 b.com 发送申请,并带上源域名。
- 作为响应,服务器返回一个带有 Access-Control-Allow-Origin: * 的 Access-Control-Allow-Origin 标头,这意味着该资源能够被任何起源拜访。(个别容许某个域或者某几个域,能够用正则)
2、会触发预检
和简略申请不同,处于平安思考,会先向“预检”申请,浏览器首先应用 OPTIONS 办法向另一个源上的资源发送 HTTP 申请,以确定理论申请是否能够平安发送。
上面是预检申请的流程:
- 首先客户端 header 头曾经不合乎简略申请的 header,这时会触发预检。
- 客户端发送 OPTIONS 申请,以获取容许跨域的 header 头,会返回 204 No Content 的状态码
- 预检胜利之后,客户端会发送失常的 POST 申请
3、nginx 跨域配置
留神:如果 nginx 设置跨域反复,客户端 console 也会提醒反复跨域
add_header Access-Control-Allow-Origin * always; # 容许所有
add_header Access-Control-Allow-Methods 'PUT,POST,GET,DELETE,OPTIONS'; #容许指定的申请办法
add_header Access-Control-Allow-Headers 'token,eceibstoken,powercode,DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; # 容许指定的 header 头
add_header Access-Control-Expose-Headers *; # 指定客户端能够拜访哪些 header
# 如果是预检申请,返回 204
if ($request_method = OPTIONS) {return 204;}