正则expression式的nginx映射吃了我的URI

有些地图杀了我的URI,我不明白为什么:

map $http_cookie $redir_scheme { default http; ~some=value https; # here is the SSL cookie } server { listen 8888; server_name redir.*; expires -1; add_header Last-Modified ""; location / { rewrite ^/(.*)$ $redir_scheme://example.com/$1 redirect; } } 

curl给没有URI的redirect:

 $ curl -giH 'Host: redir.somedomain.com' 'localhost:8888/some/path/with/meaningful/data' -H 'Cookie: some=value' (...) Location: https://example.com/ (...) 

但是当我将configuration更改为:

 map $http_cookie $redir_scheme { default http; some=value https; # here is the SSL cookie } server { listen 8888; server_name redir.*; expires -1; add_header Last-Modified ""; location / { rewrite ^/(.*)$ $redir_scheme://example.com/$1 redirect; } } 

Curl给出了一个URI的redirect:

 $ curl -giH 'Host: redir.somedomain.com' 'localhost:8888/some/path/with/meaningful/data' -H 'Cookie: some=value' (...) Location: https://example.com/some/path/with/meaningful/data (...) 

我想第一个解决scheme真的很愚蠢,但我不明白为什么。 你有光吗?

发生这种情况是因为$1来自执行的最后一个正则expression式。 由于map{}在重写中比正则expression式晚,因此$1来自映射中指定的正则expression式(它是空的)。 nginx trac中有一张关于这个的票564 ,而这个行为在forms上是正确的,这显然是反直觉的,需要改变。

作为解决方法,您可以使用命名捕获来代替:

 rewrite ^/(?<rest>.*)$ $redir_scheme://example.com/$rest redirect; 

或者,更好的是,只需使用$ request_uri return

 return 302 $redir_scheme://example.com$request_uri;