如何设置 NGINX 以部署不同的单页应用程序(SPA 的...即静态文件),具体取决于位置(在相同的 server_name 下)和子路由
Posted
技术标签:
【中文标题】如何设置 NGINX 以部署不同的单页应用程序(SPA 的...即静态文件),具体取决于位置(在相同的 server_name 下)和子路由【英文标题】:How to setup NGINX to deploy different Single Page Apps (SPA's... i.e static files) depending on location (under same server_name) with subroutes 【发布时间】:2015-10-09 18:04:43 【问题描述】:我的目标是在同一个域下设置两个不同的单页应用程序 (SPA),我们在其中显示与请求的位置/路径相对应的 SPA。我还想默认为 / 位置上的两个 SPA 之一。而且.. 如果有人在浏览器中输入 url,我希望 SPA 附加的 html5 历史位置路径实际路由到正确的位置。
举个例子更容易解释。
例子:
用户导航到 mydomain.com/app 并且服务器在 /home/user/app/dist 下提供内容(它有一个 index.html 和所有 js/css 资产)(使用 linux 所以 /home/user 只是我的主目录路径)。
用户导航到 mydomain.com/auth 并且服务器在 /home/user/auth/dist 下提供内容
用户导航到 / 并且服务器在 /home/user/auth/dist 下提供内容(默认 /navs 到 auth)
用户导航到 mydomain.com/auth/login 服务器再次提供 /home/user/auth/dist 文件夹下的内容 但 url 保持 mydomain.com/auth/login 以便 auth SPA 可以用作路由
用户导航到 mydomain.com/auth/signup 服务器再次提供 /home/user/auth/dist 文件夹下的内容 再次,url 保持 mydomain.com/auth/login 以便 auth SPA 可以用作路由
用户导航到 mydomain.com/app/home 并且服务器在 /home/user/app/dist 下提供内容
我已经尝试过 root/alias/rewrite/regex/=/^~ 规则。我正在尝试更深入地了解 nginx 设置,但与此同时,这是我目前所拥有的:
server
listen [::]:80 default_server;
listen 80;
server_name mydomain.com 127.0.0.1; # Make it serve in mydomain.com
# ^~ rules stop matching after the exact match
location ^~ /app # if location start matches /app
alias /home/user/app/dist;
index index.html;
try_files $uri $uri/ index.html =404;
# if location start matches app/lobby
location ^~ /app/home
alias /home/user/app/dist;
index index.html;
try_files $uri $uri/ index.html =404;
# you can see that I need to add a new one per each client js app route
location ^~ /app/home/visitor
alias /home/user/app/dist;
index index.html;
try_files $uri $uri/ index.html =404;
location ^~ /auth/login
alias /home/user/auth/dist;
index index.html;
try_files $uri $uri/ index.html =404;
location ^~ /auth
alias /home/user/auth/dist;
index index.html;
try_files $uri $uri/ index.html =404;
# Rewrites / to auth, appending whatever params to path
# var (for the client to consume)for now
location /
rewrite ^/(.*) /auth?path=$1 last;
它应该在 /dist 文件夹下找到一个 index.html
我想使用正则表达式或位置匹配,让客户端 js 应用程序捕捉到匹配的其余部分,这样我就不必为每个路由添加新规则(这个应用程序实际上有嵌套的状态路由)。我知道位置 ^~ 修饰符在匹配特定规则后停止,但我无法让它以任何其他方式工作。如果我不使用修饰符、正则表达式位置匹配或 = 修饰符...我只会从 nginx 收到 404、403 和 500 响应。
另外,如果我停止使用 alias/rewrite 并使用 root 关键字,它会尝试在 dist 文件夹下查找 /app 或 /auth 实际文件夹,这确实不应该(例如 if /home/user/auth /dist/auth 文件夹存在)。
我还让客户知道每个 SPA 的基本目录是什么,例如 basedir ="app"(用于应用程序)和 basedir="auth" 用于身份验证。
我认为我的重写是错误的,或者我需要更多的重写,或者额外的规则来使事情更通用。
我该怎么做呢?某种示例配置将不胜感激。谢谢。
附:如果有人好奇,我正在使用 Ember 和 Ember-cli。这会生成带有已构建应用程序的 dist/ 文件夹,并且还可以允许诸如 http://www.mydomain/app/home/visitor/comments/new 之类的路由,这就是为什么对每个路径进行硬编码没有意义(并且该应用程序仍在开发中,还有更多路由!)。
编辑
我也试过这个,我在 /app 和 /auth 路径中都得到了 404:
server
listen [::]:80 default_server;
listen 80;
server_name localhost mydomain.com 127.0.0.1;
index index.html;
location /app
root /home/user/app/dist;
try_files $uri $uri/index.html index.html;
location /auth
root /home/user/auth/dist;
try_files $uri $uri/index.html index.html;
【问题讨论】:
您使用 ipv6only 设置是否有原因? @Hevlastka 不是真的。我想复制并粘贴部分配置。让我删除它。 我删除了它@Hevlastka,并测试了配置。不会改变任何东西。但以防万一。 你试过location /auth alias /home/user/auth/dist/;
吗(抱歉格式化!)
@Hevlastka 也许。我已经尝试了很多东西。让我再试一次(以防万一),我会告诉你结果。
【参考方案1】:
首先,请确保您在 sites-enabled
中没有 default
配置,这有时可能会导致意外行为。
编辑: 最终配置如下
server
listen [::]:80 default_server;
listen 80;
server_name localhost mydomain 127.0.0.1;
location /app
alias /home/user/app/dist/;
index index.html;
try_files $uri $uri/ index.html =404;
location /auth
alias /home/user/auth/dist/;
index index.html;
try_files $uri $uri/ index.html =404;
location /
rewrite ^/(.*) /auth?$1 last;
this question 和 nginx docs 也值得一试,它们更多地解释了 root 和别名之间的区别。
【讨论】:
让我仔细检查一下这个是否有效(别名路径上没有斜杠),我会将其标记为已接受。 我错过了别名上的/
斜杠。此解决方案之所以有效,是因为它允许用户导航到 mydomain.com/app、mydomain.com/app/home、mydomain.com/auth、mydomain.com/auth/login、mydomain.com 并仍然访问静态文件(css /js) 并以正确的方式索引,即使我的客户端应用程序将路径附加到 url。感谢您的帮助@Hevlastka。
非常有用。小提示:如果您知道index.html
将始终存在,那么就不需要=404
。
我已将 Angular 生产代码复制到其中一个目录。默认 index.html 页面工作正常(domain.com/angularPages/),但是当我尝试 domain.com/angularPages/login 时,它说 404 not found.以上是关于如何设置 NGINX 以部署不同的单页应用程序(SPA 的...即静态文件),具体取决于位置(在相同的 server_name 下)和子路由的主要内容,如果未能解决你的问题,请参考以下文章
使用 Express 的单页应用程序 React 路由 URL。但不要使用 create-react-app 或 Heroku 之类的部署服务