使用nginx $ http_referer来使用不同的静态资产

时间:2017-11-25 16:35:44

标签: nginx

我试图在同一个基于nginx的服务器上部署同一个应用程序的两个不同版本。如果URL以/ v2开头,那么" v2"应该使用,否则使用v1。例如:

http://example.com/v2/x/y/z          * runs v2 app
http://example.com/anything/else     * runs v1 app

该应用程序的两个不同版本通过nginx代理,并且该部分效果很好。

问题在于我有两个静态资产目录/static/cachedassets,这两个版本对两个版本都是通用的(并且都来自/home/v1|2/www/public。所以,即使请求也是如此到http://example.com/v2/x/y/z最初将使用正确的应用,加载的网页将包含对/static/cachedassets的引用,而不包含/ v2前缀,这将从/home/v1/www/public错误地加载。

我知道引用者是一个不完美的解决方案。作为临时权宜之计,在我有机会制定更强大的解决方案之前,我尝试使用nginx的$ http_referer指向这些资产的正确位置。这是nginx文件:

server {
    listen 1.2.3.4
    server_name example.com

    ...

    location /v2 {
      root /home/v2/www/public;

      try_files $uri @proxyv2;
      access_log off;
      expires max;
    }

    location ^/(static|cachedassets) {
      root /home/v1/www/public;

      if ($http_referer ~* "/v2/") {
        root /home/v2/www/public;
      }
    }

    location / {
       root /home/v1/www/public;

       try_files $uri @proxyv1;
       access_log off;
       expires max;
    }

    location @proxyv1 {
       include uwsgi_params;
       uwsgi_pass unix:///tmp/v1-www.sock;
       uwsgi_modifier1 5;
    }

    location @proxyv2 {
       include uwsgi_params;
       uwsgi_pass unix:///tmp/v2-www.sock;
       uwsgi_modifier1 5;
    }

    ...

}

有什么想法吗?

解决方案的奖励积分,我可以轻松指定几个" v2"前缀。例如,在这里我可以指定v2,versiontwo和vtwo,以下URL将全部调用v2应用程序:

http://www.example.com/v2/something
http://www.example.com/versiontwo/abc
http://www.example.com/vtwo/abc/def/ghi

当然,http://www.example.com/somethingelse会运行v1。

我也对未使用http_referer实现此目的的其他想法持开放态度。

谢谢!

1 个答案:

答案 0 :(得分:1)

使用if变量设置map,而不是root阻止。 map可以包含许多任意复杂的正则表达式。有关详情,请参阅this document

例如:

map $http_referer $root {
    default   "/home/v1/www/public";
    ~*/v2/    "/home/v2/www/public";
}

server {
    ...
    location ~ ^/(static|cachedassets) {
        root $root;
    }
    ...
}