将使用%(QUERY_STRING)的Mod重写规则转换为NGINX重写格式?

我试图将下面的Apache / Mod_Rewrite重写规则转换为NGINX格式。 任何人都知道我要去哪里错了?

mod_rewrite的:

RewriteCond %{QUERY_STRING} topic=([0-9]+) RewriteRule /forum/index\.php /forum/vbseo301.php?action=thread&oldid=%1 [L] 

NGINX:

 location /forum/index.php { if ($args ~ "topic=([0-9]+)"){ rewrite ^/forum/index\.php?topic=(.+)$ /forum/vbseo301.php?action=thread&oldid=$1 last; } } 

这不能回答这个问题 – 请阅读评论与更多的信息,我离开这个答案主办其他变种重写可行的其他情况。

你可以做得更容易:

 # At "server" level, NOT in "location" rewrite ^/forum/index.php /forum/vbseo301.php?action=thread&oldid=$arg_topic? last; 

这个? 后缀告诉Nginx不要将原始参数追加到新的URL。

边注

顺便说一句,如果你正在做一组ID的静态映射到另一个,有一个更有效的解决方案:

 http { map $arg_topic $new_topic_id { default 1; 2 3; 4 65; } server { # some directives (server_name, listen, etc.) omitted rewrite ^/forum/index.php /forum/new.php?topic=$new_topic_id? last; # locations omitted } } 

map取第一个参数(在这种情况下来自查询字符串的topic ),并通过该表进行查找。 然后将结果分配给第二个参数( new_topic_id )。 两个好处:

  • 查找是非常有效的,因为Nginx创建一个哈希表。
  • 只有当您要使用new_topic_id (懒惰评估)

从你提供的细节我同意唯一的方法是使用, if (尽管事实if不是一般推荐)。 尝试这个:

 location /forum/index.php { if ($arg_topic != "") { rewrite ^ /forum/vbseo301.php?action=thread&oldid=$arg_topic? break; } } 

我会留下我以前的答案,因为这可能是对别人的帮助。

简单的例子,以确保这个工程

我已经提出了一个更简单的例子来展示这个作品。 这里是Nginx配置片段:

 location /index.html { if ($arg_topic != '') { rewrite ^ /vv.html?t=$arg_topic? break; } ssi on; root /home/alaz; } location /vv.html { ssi on; root /home/alaz; } 

index.html内容:

 <b>index</b> <br/> topic: <!--#echo var="arg_topic" --> 

vv.html内容:

 <b>vv</b> <br/> topic: <!--#echo var="arg_topic" --> <br/> t: <!--#echo var="arg_t" --> 

现在重新加载Nginx,然后将浏览器指向http://hostname/index.html ,之后再点击http://hostname/index.html?topic=11 。

似乎很多人仍然在看这个问题。 希望我的回答有帮助!

 location /forum/index.php { if ($args ~ "topic=([0-9]+)"){ rewrite ^/forum/index\.php$ /forum/vbseo301.php?action=thread&oldid=$arg_topic? last; } } 

经过测试,它的工作。 重写行中的一些重要但微妙的修复:

  1. 我从旧的url中删除了查询字符串部分“?topic =(。+)”,因为nginx重写规则与查询字符串根本不匹配(在nginx中也称为args)。 它只会尝试匹配PATH。 参考链接
  2. 参数topic = xxxx自动存储在nginx中的变量$ arg_topic中。 所以我可以简单地把“oldid = $ arg_topic”放在新的url中。 参考链接
  3. 我把一个问号“?” 在新的URL的末尾,以便nginx不会尝试从旧的URL附加查询字符串。 默认情况下,nginx将从旧的URL附加整个查询字符串。