使用 nginx $http_referer 使用不同的静态资源

yah*_*ann 1 nginx

我正在尝试在同一台基于 nginx 的服务器上部署同一应用程序的两个不同版本。如果 URL 以 /v2 开头,则应使用“v2”,否则使用 v1。例子:

http://example.com/v2/x/y/z          * runs v2 app
http://example.com/anything/else     * runs v1 app
Run Code Online (Sandbox Code Playgroud)

该应用程序的两个不同版本通过 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;
    }

    ...

}
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?

我可以轻松指定几个“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
Run Code Online (Sandbox Code Playgroud)

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

我也对不使用 http_referer 来完成此任务的其他想法持开放态度。

谢谢!

Ric*_*ith 6

if使用变量来map设置root. 可以map包含多个任意复杂的正则表达式。请参阅此文档了解更多信息。

例如:

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

server {
    ...
    location ~ ^/(static|cachedassets) {
        root $root;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)