Angular URL 中包含数据的应用从 NGINX 获取 404

Angular App with Data in the URL gets 404 from NGINX

我有一台服务器采用此设置:

在根 (/var/www) 文件夹中,我有一个 index.html 链接到 angular app1app2

   \index.html
   |
   +-\app1\index.html
   |
   +-\app2\index.html

我的 angular app2 在 URL 中有数据,所以我的 URL 看起来像这样:

https://www.example.com/app2/thispartisdata/AlongDataStringThatContainsData

当我浏览到 https://www.example.com/app2 时一切正常

当我浏览到 https://www.example.com/app2/somedata 时,这会转到来自 NGINX

404 消息

我已经尝试了 try_files 配置选项,但我只需要它用于我的第二个应用程序。

所以我想做的是这样的事情(但我不知道或找不到语法是什么,或者它是否可能)

location /app2 {
    try_files $uri $uri/ /app2/index.html;
}

我无法使上述工作正常。我想请求 app2 将整个 URL 传递给 app2 而不是 NGINX 妨碍和 return 一个 404。我找不到正确的方法让 app2 接收完整的 URL 并将完整的 URL 重定向到 app2 的 index.html.

编辑

我的完整配置:

server {

        server_name example.com www.example.com;

        location /app1/api/ {
                proxy_pass https://127.0.0.1:5001;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection keep-alive;
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
       }

        location /app2/api/ {
                proxy_read_timeout 300s;
                proxy_connect_timeout 75s;
                proxy_pass https://127.0.0.1:5002/;
                proxy_http_version 1.1;
                proxy_request_buffering off;
                proxy_buffering off;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection keep-alive;
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
        }

# I want to do something like this here, but this give a 500 error
#
#        location /app2 {
#             try_files $uri /app2/index.html;
#        }

        location / {
                root /var/www;
                index index.html;
        }


    ssl_stapling on;
    ssl_stapling_verify on;
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}


server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot



        server_name example.com www.example.com;
    listen 80;
    return 404; # managed by Certbot

}

您在这里的主要错误是您没有在 server 级别为您的网站定义 root。您的 root /var/www; 仅在 location / { ... } 中有效,在其他任何地方均无效。与许多其他 nginx 指令一样,root 指令如果不是从以前的配置级别继承的,则相对于 nginx prefix 具有默认值 /html。该前缀是在构建时指定的,可以使用 nginx -V 命令检查(请参阅 --prefix=... 配置参数)。例如,如果此前缀等于 /etc/nginx(常见情况),则默认服务器 webroot 将为 /etc/nginx/html。您需要将该指令向上移动一级,到 server 上下文而不是 location 上下文。

完成后,您可以添加

location /app2/ {
    try_files $uri /app2/index.html;
}

到您的 server 街区。我在这里不使用 $uri/ 组件,因为我不希望您的 app2 网络应用程序目录下有任何嵌套的 index.html 除了 /app2/index.html一。从 /app2 重定向到 /app2/ 将由 nginx 自动进行,因为在你的 location / { ... } 下,隐式 try_files $uri $uri/ =404 将用作默认的 PRECONTENT 请求处理阶段处理程序, /app2 请求将由 location / { ... } 而不是 location /app2/ { ... }.

处理

我不明白的是,如果没有类似的

,您的 app1 是如何工作的
location /app1/ {
    try_files $uri /app1/index.html;
}

位置块。也许它没有交互部分,仅用作 API?

接下来我觉得有点奇怪的是你的 app1/app2 API 位置。您在第二个位置 (proxy_pass https://127.0.0.1:5002/;) 中为 proxy_pass 指令使用 URI 后缀,而在第一个位置 (proxy_pass https://127.0.0.1:5001;) 中未使用它。这意味着像 /app1/api/endpoint 这样的请求将按原样出现在您的 app1 中,而像 /app2/api/endpoint 这样的请求将出现在您的 app2[=79= 中] 为 /endpoint。如果您使用 proxy_pass https://127.0.0.1:5001/app1/;proxy_pass https://127.0.0.1:5002/app2/;,那么这两个请求都会在您的后端显示为 /api/endpoint。您可以找到有关此 proxy_pass 指令行为 的更多信息。但是,如果两个 API 都按预期工作,那么您的后端应用程序可能需要不同形式的请求,您不需要更改任何内容。尽管如此,我认为值得一提的是这种差异。

最后一件事是关于代理 API 请求的其他设置。我从未见过任何明确使用 proxy_set_header Connection keep-alive; 的配置;保持与上游连接的常用方法是使用 upstream block with the keepalive parameter specified (example). The proxy_set_header Upgrade $http_upgrade; most likely have been taken from the official WebSocket proxying example and makes no sense here without the rest of that configuration. More technical details about those HTTP headers and related subjects from MDN: Connection, Keep-Alive, Upgrade 声明它。通过 proxy_request_buffering off;proxy_buffering off; 禁用 request/response 缓冲在应用于 API 调用时对我来说也很奇怪;通常当您需要某种关于 request/response 进度的 real-time 信息时使用它,而 API 调用不太可能。