发现 Nginx 可以通过 proxy_set_header
来解决 CORS 问题,Caddy 也可以通过 header
来解决。
代码
一般情况下的部署是这样的,但是没有转发后端接口
1 2 3 4 5 6 7
| :80 { header / { Access-Control-Allow-Origin * Access-Control-Allow-Methods GET, POST, OPTIONS Access-Control-Allow-Headers Origin, X-Requested-With, Content-Type, Accept } }
|
如果需要转发后端接口,可以这样
1 2 3 4 5 6 7 8
| :80 { header /api/* { Access-Control-Allow-Origin * Access-Control-Allow-Methods GET, POST, OPTIONS Access-Control-Allow-Headers Origin, X-Requested-With, Content-Type, Accept } reverse_proxy /api/* http://localhost:3000 }
|
比较成熟的方案
一般方案
1 2 3 4 5 6 7
| :8088 { reverse_proxy /* http://xxxx:80 { header_up Host {http.reverse_proxy.upstream.hostport} header_down Access-Control-Allow-Headers * header_down Access-Control-Allow-Origin * } }
|
带模块的方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| (cors) { @cors_preflight method OPTIONS @cors header Origin {args.0}
handle @cors_preflight { header Access-Control-Allow-Origin "{args.0}" header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE" header Access-Control-Allow-Headers "Content-Type" header Access-Control-Max-Age "3600" respond "" 204 }
handle @cors { header Access-Control-Allow-Origin "{args.0}" header Access-Control-Expose-Headers "Link" } }
example.com { import cors https://example.com reverse_proxy localhost:8080 }
|
这是网上看到的,但是存在一个问题就是写死的不够智能,比如 Access-Control-Allow-Origin
的值是 *
,在请求参数中有 Cookie 的情况下就不能实现动态的跨域了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| (cors) { @cors_preflight method OPTIONS @cors header Origin {http.request.header.Origin}
handle @cors_preflight { header Access-Control-Allow-Origin {http.request.header.Origin} header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE" header Access-Control-Allow-Headers "Content-Type, x-xsrf-token" header Access-Control-Max-Age "3600" header Access-Control-Allow-Credentials true respond "" 204 } }
:8088 { import cors http://localhost:8088 reverse_proxy http://192.168.234.49:8080 }
|
还有个写法是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| (cors) { @origin{args.0} header Origin {args.0} header @origin{args.0} Access-Control-Allow-Origin "{args.0}" header @origin{args.0} Access-Control-Allow-Headers "content-type, x-requested-with" header @origin{args.0} Vary Origin } myawesomewebsite.com { root * /srv/public/ file_server header Access-Control-Allow-Methods "POST, GET, OPTIONS" @options { method OPTIONS } respond @options 204 import cors https://member.myawesomewebsite.com import cors https://customer.myawesomewebsite.com }
|
后记
如果请求参数中有 Cookie 的情况下,需要设置 Access-Control-Allow-Credentials
为 true
,并且 Access-Control-Allow-Origin
的值不能为 *
,需要设置为请求的域名。
参考
这个是占位符的文档,可以看到有很多占位符可以使用
这个是匹配器
这个是官方 Demo
Caddy 实战
还有个Whistle也可以解决跨域,这儿就不多说了