我有一个用作反向代理的 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
也是一个很好的调试工具。