Nginx $ request_uri有重复的查询参数

min*_*nel 7 nginx

我发现nginx的$ request_uri复制了查询参数.

我希望实现的目标是将裸域的任何请求重定向到www域.这是一个示例配置.

    server {
        listen       8080;
        server_name  localhost;    
        location / {
            if ($http_host !~* "^www\.") {
                rewrite (.*) http://www.$http_host$request_uri permanent;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我得到的结果是:

curl -I http://127.0.0.1:8080/pp/\?a\=b

HTTP/1.1 301 Moved Permanently
Server: nginx/1.6.2
Date: Thu, 22 Jan 2015 04:07:39 GMT
Content-Type: text/html
Content-Length: 184
Connection: keep-alive
Location: http://www.127.0.0.1:8080/pp/?a=b?a=b
Run Code Online (Sandbox Code Playgroud)

查询参数在结果中重复; 我在这里错过了什么吗?

Day*_*ayo 12

您看到的查询参数的复制是Nginx的预期行为.要更改此设置,您需要?在重写中添加一个尾随,如下所示:

   server {
        listen       8080;
        server_name  localhost;    
        location / {
            if ($http_host !~* "^www\.") {
                rewrite (.*) http://www.$http_host$request_uri? permanent;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

见文档这里.

如果替换字符串包含新请求参数,则先前的请求参数将附加在它们之后.如果这是不希望的,在替换字符串的末尾加上一个问号可以避免附加它们,例如:

重写^/users /(.*)$/show?user = $ 1?持续;

但是,Aleksey Deryagin给出的配置对于您所需的重定向类型来说是更好,更有效的选项,因为if无论是否需要,每个请求都将按原始配置中的块进行评估.


Ale*_*gin 3

if 是邪恶的(并非总是如此,但是)所以为什么不尝试 return 301:

server {
  server_name example.com;
  return 301 $scheme://www.example.com$request_uri;
}

server {
  server_name www.example.com;
  root /var/www;
  location / {
    index index.html;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • return 301 是比重写更好的做法,所以我在示例中使用 return :) (3认同)
  • 我改进了您的代码,在重定向 URL 中使用 `$scheme` 而不是硬编码 `http://`,这样该示例就可以无缝地用于 HTTP 和 HTTPS。 (2认同)