我不明白为什么nginx要在location语句之前执行If语句。更确切地说,为什么nginx不执行返回语句,然后停止处理?
如果打开/xyz,即使$http_x_forwarded_host不是www.acme.com,也会得到带有"hello world“的200,因为if语句位于location语句的下方。但是nginx只是点亮了location语句并运行到if子句中。有什么想法吗?我没有运气就试了break;。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
index index.html index.htm index.php;
location /xyz {
return 200 'hello world';
}
if ($http_x_forwarded_host != "www.acme.com") {
return 301 https://www.acme.com$uri;
}
}发布于 2020-11-13 20:42:23
您是对的,在ngx_http_rewrite_module的位置选择机制取代之前,来自的所有指令都是执行的。使用break指令意味着从重写模块中断这些指令的执行,并根据最佳匹配位置立即强制执行请求。这是因为虽然nginx配置通常是声明性的,但重写模块必须对其指令进行评估。对于每一位初入职场的人来说,这都是一个困惑的来源。您可以阅读更多关于重写模块内部实现这里的信息。
尽管如此,您不能用配置来实现这种行为。这并不意味着您根本无法实现您想要的,可能的解决方案之一是使用regex负前瞻性功能:
if ($http_x_forwarded_host != "www.acme.com") {
# do the redirect only if the URI doesn't start with '/xyz'
rewrite ^(?!/xyz) https://www.acme.com$uri permanent;
}
location /xyz {
return 200 'hello world';
}如果您想做一些复杂的请求处理而不是重定向,可以使用internal位置:
if ($http_x_forwarded_host != "www.acme.com") {
# in case you will need an original URI later, you can save its value
# set $original_uri $uri;
# process the request with the special location only if the URI doesn't start with '/xyz'
rewrite ^(?!/xyz) /special;
}
location /xyz {
return 200 'hello world';
}
location /special {
internal;
... # any custom processing here, for example 'return 403;'
}显然,对于这样的位置,您应该选择URI前缀,而不是以任何方式干扰现有站点。
发布于 2020-11-13 20:10:53
我认为这是因为重定向后,它再次到达您的网站。也许重定向是指向与位置相同的主机?
https://stackoverflow.com/questions/64827335
复制相似问题