我有以下配置:
upstream ring {
server 127.0.0.1:3000 fail_timeout=0;
}
server {
root /home/app/public;
index index.dev.html;
server_name localhost;
location / {
try_files $uri $uri/ @ring;
}
location @ring {
proxy_pass http://ring;
proxy_set_header Host $http_host;
proxy_buffering off;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
它先充当文件,然后充当目录,最后充当应用服务器的代理。这按预期工作。但是,现在,我希望在用户第一次访问该网站时将其重定向到 about.html 页面。因此,我将配置更改为以下内容:
upstream ring {
server 127.0.0.1:3000 fail_timeout=0;
}
server {
root /home/app/public;
index index.dev.html;
server_name localhost;
location / {
set $seen false;
if ($http_cookie ~* "seen") {
set $seen true;
}
if ($seen = false) {
add_header Set-Cookie seen=1;
return 302 $scheme://$host/about.html;
}
try_files $uri $uri/ @ring;
}
location @ring {
proxy_pass http://ring;
proxy_set_header Host $http_host;
proxy_buffering off;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
重定向逻辑现在有效(没有 cookie 重定向到具有新 cookie 集的 about.html,后续请求将转到主 index.html 页面)。但是,现在任何指向应用服务器的 URL 都会导致 404 错误。@ring 位置不再提供服务。
我可能犯了一个愚蠢的错误,但是对 nginx 了解不够,无法调试这个问题。
多谢。
答案1
好吧,事实证明 nginx 中的“if 是邪恶的”(https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/),这是由于“if”是命令式的而其余配置是声明式的而导致的一个错误。
以下更改有效,并实现了我想要的一切。诀窍是除了 return 或 rewrite 之外,不在 if 内部执行任何操作。然后还要使用 nginx 内部重定向代码 418。
upstream ring {
server 127.0.0.1:3000 fail_timeout=0;
}
server {
root /home/app/public;
index index.dev.html;
server_name localhost;
location / {
error_page 418 = @about;
if ($cookie_seen != 1) {
return 418;
}
try_files $uri $uri/ @ring;
}
location @about {
add_header Set-Cookie seen=1;
return 302 $scheme://$host/about.html;
}
location @ring {
proxy_pass http://ring;
proxy_set_header Host $http_host;
proxy_buffering off;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}