如何防止Nginx转义网址或变量?

时间:2018-11-26 12:33:56

标签: nginx

我正在尝试从url中剥离一些“不良”字符,然后重定向到固定版本,但是由于nginx将uri的其余部分加倍转义,因此无法正常工作。

if ($request_uri ~ "^(.*?)%E2%86%92(.*)"){
  set $u $1$2;
  rewrite ^ $u? permanent;
}
#note: I need to use $request_uri to include the query string

然后是GET /ro→bot→s.txt?aa→bb

然后我最终重定向到/robot%25E2%2586%2592s.txt?aa%25E2%2586%2592bb

请注意,%E2%86%92的第一个实例被剥离,而其他实例被两次转义,这防止了原本应该剥离它们的重定向循环。

经过一些试验后,我现在陷入了无法理解的行为。此配置:

if ($request_uri ~ "^(.*?)%E2%86%92(.*)"){
  set $u "$1$2";
  return 400 "$u\n$1$2";
}

输出以下结果:

/robot%25E2%2586%2592s.txt%3Faa%25E2%2586%2592bb
/robot%E2%86%92s.txt?aa%E2%86%92bb

怎么可能将$ u设置为$ 1 $ 2,但是$ u与输出中的$ 1 $ 2不同呢?

又如何防止nginx转义这些值?


更新

我发现了两个解决此问题的方法。一种是先重写路径:

rewrite  "^(.*)→(.*)$"  $proto://$host$1$2  permanent;
if ($request_uri ~ "^(.*?)%E2%86%92(.*)"){
  set $u $1$2;
  rewrite ^ $proto://$host$u? permanent;
}

那么看来,如果url的路径部分没有改变,那会修改查询字符串的转义行为吗?

另一种解决方法是直接使用$ 1 $ 2捕获进行重定向,而无需中间变量:

if ($request_uri ~ "^(.*?)%E2%86%92(.*)"){
  set $u $1$2;
  #return 301 $proto://$host$u; #this doesn't work
  return 301 $proto://$host$1$2; #but this does
}

我不明白为什么会发生任何的情况,所以我还是很感激。

0 个答案:

没有答案