我有这个 nginx 配置文件:
map $request_uri $new_uri {
default DEFAULT;
/shell http://shell.com;
/lol http://lol.com;
}
map $request_uri $ret_code {
default 301;
/shell 301;
/lol 302;
}
server {
listen 80;
server_name TestDomain.com www.TestDomain.com;
location / {
add_header X-request_uri $request_uri;
add_header X-new_uri $new_uri;
add_header X-return_code $ret_code;
if ($new_uri = "DEFAULT") {
return 301 https://ashfame.com$request_uri;
}
if ($ret_code = 301) {
return 301 $new_uri;
}
if ($ret_code = 302) {
return 302 $new_uri;
}
}
}
map 指令根本不起作用,只是默认使用它的默认定义。
例如:
$ curl -I testdomain.com/lol
HTTP/1.1 301 Moved Permanently
Server: nginx/1.10.0 (Ubuntu)
Date: Sun, 22 Jan 2017 20:04:06 GMT
Content-Type: text/html
Content-Length: 194
Connection: keep-alive
Location: https://ashfame.com/lol
X-request_uri: /lol
X-new_uri: DEFAULT
X-return_code: 301
/lol
应该设置$new_uri
为http://lol.com
和$ret_code
,302
但如果你看看X-
标题,它只是采用映射中指定的默认值。
一周前,我让相同的 nginx 配置运行起来,从那时起就没有任何变化。我确实开启了 ubuntu 的自动安全升级,但我认为 nginx 甚至没有更新。正在运行v1.10.0
。无法真正指出为什么它停止工作。
编辑:刚刚在不同的 VPS 上测试了同样的配置,同样的 nginx 版本,它在那里工作正常。我现在该如何修复这个问题?
答案1
我找到了问题所在。每个域都有多个这样的配置文件,由于 map 是在 http 上下文中定义的,所以最后一个配置文件会覆盖变量的值。我通过在每个配置文件中为变量名添加后缀来解决这个问题,这样变量就是唯一的:
map $request_uri $new_uri_5 {
default DEFAULT;
/shell http://shell.com;
/lol http://lol.com;
}
map $request_uri $ret_code_5 {
default 301;
/shell 301;
/lol 302;
}
server {
listen 80;
server_name TestDomain.com www.TestDomain.com testdomain.com www.testdomain.com;
location / {
add_header X-request_uri $request_uri;
add_header X-new_uri $new_uri_5;
add_header X-return_code $ret_code_5;
if ($new_uri_5 = "DEFAULT") {
return 301 https://ashfame.com$request_uri;
}
if ($ret_code_5 = 301) {
return 301 $new_uri_5;
}
if ($ret_code_5 = 302) {
return 302 $new_uri_5;
}
}
}
5 是我的系统中这个特定域的 ID。
答案2
我在 Nginx 1.12.2 上遇到了同样的问题——map 指令无法匹配任何模式,即使是最简单、最简单的模式,例如/
,并且始终使用默认值。
$uri
问题是由于在映射中使用了变量而导致的。某些 Nginx 配置$uri
通过添加前缀隐式修改了其原始值/index.php
,从而导致模式不匹配。这种行为是$uri
设计使然,两者之间的确切区别$request_uri
和$uri
变量。
修复方法是替换 Nginx 配置中的 URI 变量:
map $uri $result_var {
# ...
}
内容如下:
map $request_uri $result_var {
# ...
}