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 OK
为https://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 的默认路由!
我正在尝试提供两个不同版本的单页应用程序 - 一个是使用全新的、闪亮的 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 OK
为https://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 的默认路由!