Nginx map 指令与规则不匹配

Nginx map 指令与规则不匹配

我有这个 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_urihttp://lol.com$ret_code302但如果你看看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 {
    # ...
}

相关内容