【工作】面试——前端linux learn

CORS & nginx配置CORS实现跨域

2020-07-28  本文已影响0人  nico1988

<meta name="source" content="lake">

出于安全原因,浏览器限制从脚本发起的跨源HTTP请求。例如,XMLHttpRequest和Fetch API遵循同源策略。这意味着,使用这些api的web应用程序只能从加载该应用程序的同一源请求资源,除非来自其他源的响应包含正确的CORS头文件。

image

同源和非同源请求 图片来源 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

1 什么是同源策略(Same-origin policy)

简单来说就是一句话: URL中的协议名(scheme)、域名(host)、端口号(port)全部都得相等

<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"> hierarchical part ┌───────────────────┴─────────────────────┐ authority path ┌───────────────┴───────────────┐┌───┴────┐ abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1 └┬┘ └───────┬───────┘ └────┬────┘ └┬┘ └─────────┬─────────┘ └──┬──┘ scheme user information host port query fragment</pre>

URL

<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">URL 说明 是否允许通信 http://www.domain.com/a.js http://www.domain.com/b.js 同一域名,不同文件或路径 允许 http://www.domain.com/lab/c.js http://www.domain.com:8000/a.js http://www.domain.com/b.js 同一域名,不同端口 不允许 http://www.domain.com/a.js https://www.domain.com/b.js 同一域名,不同协议 不允许 http://www.domain.com/a.js http://192.168.4.12/b.js 域名和域名对应相同ip 不允许 http://www.domain.com/a.js http://x.domain.com/b.js 主域相同,子域不同 不允许 http://domain.com/c.js http://www.domain1.com/a.js http://www.domain2.com/b.js 不同域名 不允许</pre>

常见跨域场景

2 常见跨域解决方案

1、 通过jsonp跨域

2、 document.domain + iframe跨域

3、 location.hash + iframe

4、 window.name + iframe跨域

5、 postMessage跨域

6、 跨域资源共享(CORS)

7、 nginx代理跨域

8、 nodejs中间件代理跨域

9、 WebSocket协议跨域

3 什么是CORS(Cross-Origin Resource Sharing (CORS))

3.1 什么是CORS

MDN Cross-Origin Resource Sharing (CORS)

阮一峰 跨域资源共享 CORS 详解 关于CORS阮一峰老师写的绝对是经典

3.2 CORS分类

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

3.3 简单请求

1 Simple method: GET, POST or HEAD

2 Simple headers– the only allowed custom headers are:

3.4 非简单请求

除了简单请求都是非简单请求

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询(OPTIONS)请求,称为"预检"请求(preflight)有的场景忽略了预检请求的nginx配置,导致跨域配置失败

image

非简单请求 预检请求流程(OPTIONS)

4 nginx配置CORS

<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);"># # Wide-open CORS config for nginx # location / { if (request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always; # # Custom headers and headers various browsers *should* be OK with but aren't # add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; always # # Tell client that this pre-flight info is valid for 20 days # add_header 'Access-Control-Max-Age' 1728000 always; add_header 'Content-Type' 'text/plain; charset=utf-8' always; add_header 'Content-Length' 0 always; return 204; } if (request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '' always; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; } } </pre>

https://enable-cors.org/server_nginx.html

踩坑

nginx: [emerg] "add_header" directive is not allowed here -

没有返回跨域头信息 - 可能只是配置了某个location下面的跨域头配置,可能是返回的状态码有404等状态码,浏览器不认可返回的跨域头配置

预检请求没通过 - 没有处理OPTIONS请求或者,OPTIONS没有返回对应的状态码

参考资料

阮一峰 跨域资源共享 CORS 详解

MDN Cross-Origin Resource Sharing (CORS)CORS on Nginx

Same-origin policy

前端常见跨域解决方案(全)

ngx_http_headers_module

上一篇下一篇

猜你喜欢

热点阅读