nginx配置CORS实现跨域

场景

最近有个上传图片的需求,为了分流,将接口部署到另一个单独的域名,所以需要解决跨域的问题。

思路

一开始想着在后端代码直接设置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参数等方式去传递。

nginx配置

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;
}

相关推荐