为什么“/”nginx 位置规则无法捕获某些 URL?它不是应该与所有 URL 一起使用吗?

为什么“/”nginx 位置规则无法捕获某些 URL?它不是应该与所有 URL 一起使用吗?

我有一个用作反向代理的 nginx,它根据请求 URL 将请求重定向到 angular 应用程序或 node js 后端应用程序。还有一条location ~ /s/(cas)/(.*)提供静态内容的规则(尽管我现在看到,如果“/”也捕获了此路由,则不需要该规则,因为静态内容也保存在 backend:4000)。

我特别关注的是最常见的规则“/”,它应该抓住所有未落入任何其他位置的请求,它无法正确应用于某些 URL,导致 nginx 发送其 50x.html 错误页面。具体来说,我的问题是此重定向似乎无法捕获所有不符合先前规则的流量。并且是负责重定向应落入角度应用程序的流量的一条规则。

如果我是对的,这应该属于“/”规则:

https://SUBDOMAIN.DOMAIN.es/user/trip/13925/instant?sharedToken=[REDACTED]

这些至少应该通过“/”规则正确重定向,而且还要在大量超时后显示 nginx 失败页面:

https://SUBDOMAIN.DOMAIN.es/user/trip/foo/instant?sharedToken=[REDACTED] # changed id for "foo"
https://SUBDOMAIN.DOMAIN.es/user/trip/instant?sharedToken=[REDACTED] # removed id segment of url
https://SUBDOMAIN.DOMAIN.es/user/instant?sharedToken=[REDACTED] # also removed "trip" segment of url

该 URL 的任何其他变体均可正常工作,并重定向到 https://backend:4000。

那么,为什么这些规则没有被位置“/”捕获呢?

这是 nginx 配置文件。我们故意省略了域名和子域名:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    expires $expires;
    add_header Strict-Transport-Security "max-age=15768000; includeSubDomains" always;
    server_name [SUBDOMAIN].[DOMAIN_NAME].es;
    ssl_certificate /etc/nginx/ssl/CERT.crt;
    ssl_certificate_key /etc/nginx/ssl/CERT.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    ssl_session_cache shared:SSL:5m;
    ssl_session_timeout 1h;
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 256;
    gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

    location ~ /api(?<url>/.*)  {
        resolver 127.0.0.11;
        set $target http://backend:5000/api${url}$is_args$args;
        proxy_set_header X-Forwarded-Host $host;     # Relay whatever hostname was received
        proxy_set_header X-Forwarded-Proto $scheme;  # Relay either http or https
        proxy_set_header X-Forwarded-Server $host;   # Relay whatever hostname was received
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Prefix /api/;
        proxy_set_header Host "SUBDOMAIN.DOMAIN.es";

        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Max-Age 3600;
        add_header Access-Control-Expose-Headers Content-Length;
        add_header Access-Control-Allow-Headers Range;

    ## Websockets support 2/2
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    ## END Websockets support 2/2

        proxy_pass $target;
        client_max_body_size 10M;
    }

    location ^~ /_assets/ {
        alias /usr/share/nginx/html/assets/;
    }

    location ^~ /.well-known/acme-challenge/ {
        alias /usr/share/nginx/html/.well-known/acme-challenge/;
    }

    location ~ /s/(cas)/(.*) {
        add_header Pragma "no-cache";
        add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
        proxy_pass http://backend:4000;
    }

    location / {
        #root /usr/share/nginx/html;
        proxy_pass http://backend:4000;
        expires -1;
        proxy_set_header X-Forwarded-Host "SUBDOMAIN.DOMAIN.es";
        proxy_set_header X-Forwarded-Server "SUBDOMAIN.DOMAIN.es";
        proxy_set_header Host "SUBDOMAIN.DOMAIN.es";

        add_header Pragma "no-cache";
        add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";

        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Max-Age 3600;
        add_header Access-Control-Expose-Headers Content-Length;
        add_header Access-Control-Allow-Headers Range;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

答案1

这些至少应该通过“/”规则正确重定向,而且还要在大量超时后显示 nginx 失败页面:

这表明您的应用程序超时了。nginx 错误页面立即出现。

您应该检查后端应用程序的日志,了解当您发出需要很长时间的请求然后显示失败页面时发生了什么。

在这种情况下, nginxerror.log也是一个很好的调试工具。

相关内容