xiedengmin 2019-06-26
最近有个上传图片的需求,为了分流,将接口部署到另一个单独的域名,所以需要解决跨域的问题。
一开始想着在后端代码直接设置cors策略,后来发现请求都是从nginx进入,所以将cors移动到nginx下实现。同时只能对指定子域名放开访问权限,所以设置如下。
Access-Control-Allow-Origin *.test.com
亲测不可用,只能是*和指定的域名。
还好nginx支持if指令,对域名做下正则校验就可以实现指定子域名跨域。
接下来测试发现浏览器的options发到后端后,没有处理返回了一些莫名其妙的东西。
好吧直接在nginx返回不发给后端,还是用if指令判断http请求类型。
这里就用了两个if,最坑的事情出现了,nginx在多个if指令下,有些指令是最后一个if才有效,前面的会被覆盖。
最终还是直接重复add_header解决。
客户端ajax请求withCredentials属性设置为true才会发送cookie。
同时cookie要是上传域名可用的,不然还是要通过url参数等方式去传递。
location / { # 检查域名后缀 if ($http_origin ~ \.test\.com) { add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Methods GET,POST,OPTIONS; add_header Access-Control-Allow-Credentials true; add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type; add_header Access-Control-Max-Age 1728000; } # options请求不转给后端,直接返回204 # 第二个if会导致上面的add_header无效,这是nginx的问题,这里直接重复执行下 if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Methods GET,POST,OPTIONS; add_header Access-Control-Allow-Credentials true; add_header Access-Control-Allow-Headers DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type; add_header Access-Control-Max-Age 1728000; return 204; } # 其他请求代理到后端 proxy_set_header Host $host; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://xxx.xxx.xxx.xxx; }