nginx - 为不同的单页应用程序提供多个根

nginx - Serve multiple roots for different single page applications

我正在尝试提供两个不同版本的单页应用程序 - 一个是使用全新的、闪亮的 JS 框架构建的,另一个是使用旧的、更糟糕的 JS 框架构建的。所有重要的特性和功能都在新 SPA 中,所有非关键特性和功能都在旧 SPA 中,并且正在移植中。

考虑到这一点,我正在尝试通过路径使旧的 SPA 可用,例如/old-app.

新应用位于 /www/new-app。 旧应用位于 /www/old-app.

这是我试过的:

server {
  listen 443;

  root /www/new-app;
  index index.html;

  location / { # default to new app
    try_files $uri @prerender;
  }

  location /old-app {
    root /www/old-app; # I have also tried *alias* instead of *root* here
    index index.html;
    try_files $uri @prerender;
  }

  location @prerender {
    set $prerender = 0;

    # a bunch of rules for prerender from here: https://gist.github.com/thoop/8165802

    if ($prerender = 1) {
      proxy_pass http://127.0.0.1:8080/$scheme://$host$request_uri;
    }

    if ($prerender = 0) {
      rewrite .* /index.html break;
    }
  }
}

上面returns一个200 OKhttps://www.domain.example/old-app/<route>,但服务的页面不是/www/old-app/index.html。相反,提供的文件来自 /www/new-app/index.html,带有空白页,大概是因为新 SPA 不理解提供的 /<route>,只有旧 SPA 理解。

这里有两处错误。

location /old-app {
    root /www/old-app;

这将在 /www/old-app/old-app 查找文件(有关详细信息,请参阅 this document)。

try_files $uri @prerender;

这会将您的所有路由发送到 location @prerender 块,该块以 rewrite .* /index.html break;

结尾

可能有更优雅的解决方案,但您可以添加第二个“prerender”块,例如 location @oldrender 与原来的相似,但以 rewrite ^ /old-app/index.html last;[=21 结尾=]

例如:

location /old-app {
    root /www;
    try_files $uri @oldrender;
}
location @oldrender {
    ...
        rewrite ^ /old-app/index.html last;
    ...
}

请注意 root 已更改,您需要使用 rewrite...last

虽然 Richard 的答案有效并且可能比我的更正确,但经过大量试验和错误后,我最终得到了以下配置(在 Richard 有机会 post 他的答案之前!)。我 post 出于 post 的诚意,如果其他人有与我相同的要求。

server {
  listen 443;

  root /www/new-app;
  index index.html;

  # I left the following alone
  location / {
    try_files $uri @prerender;
  }

  # Here's the meat of what worked
  location /old-app {
    alias /www/old-app;
    index index.html;
    try_files $uri $uri/ index.html;
  }
}

最后,在旧的单页应用程序的 index.html 中,我添加了一个 <base href="/old-app/" /> 以确保从正确的服务器路径提供对图像、样式表等的任何引用。

现在,访问 http://domain.example/old-app 正确服务于旧 SPA 的默认路由!