nginx配置CORS实现跨域

场景

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

思路

一开始想着在后端代码直接设置cors策略,后来发现请求都是从nginx进入,因此将cors移动到nginx下实现。同时只能对指定子域名放开访问权限,因此设置以下。ajax

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;
}
相关文章
相关标签/搜索