Apache mod_rewrite规则顺序混乱

我正在尝试设置一些简单的规则,根据path和查询string的位来重写旧版网站的URL。

首先,看起来像这样:

RewriteEngine on RewriteMap freeitems txt:/www/www.example.com/etc/freeitems_map.txt RewriteMap items txt:/www/www.example.com/etc/items_map.txt RewriteCond %{QUERY_STRING} ^sku=(\d+)$ RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}? RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}? 

对于/free_item.phpurl来说,这似乎很好,正确地从RewriteMap取代了结果,但是/item.php只返回了redirect的URL的第一部分,而没有从RewriteMap查找中得到结果。 如果我颠倒了规则的顺序,失败/正在运行的URL就会颠倒过来。 正如我一直理解RewriteRule语法,如果URLpath不匹配模式,规则将被跳过,处理移动到下一个。 在这种情况下,

我最终设法通过将其分解成两个块来实现它的工作:

 RewriteEngine on RewriteMap freeitems txt:/www/www.example.com/etc/freeitems_map.txt RewriteMap items txt:/www/www.example.com/etc/items_map.txt RewriteCond %{QUERY_STRING} ^sku=(\d+)$ RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}? RewriteCond %{QUERY_STRING} ^sku=(\d+)$ RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}? 

任何人都可以启发我为什么第一种技术失败?

编辑:作为一个testing,我添加了第二个RewriteRuleredirect的URL的附加path元素。 当我请求一个应该匹配第二个规则而不是第一个的URL时,该path元素将按预期显示。 只是不是RewriteMap查找的结果。

谢谢!

-ben

第一种技术失败的原因是因为第二个RewriteRule上的RewriteCond%1反向引用不存在。 每个RewriteRule都有自己的一套RewriteCond,不会与其他RewriteRule块共享RewriteCond。

请参阅: http : //httpd.apache.org/docs/2.0/mod/mod_rewrite.html#InternalRuleset

我还build议添加[L]标志,因为看来每个规则都是独立的。 例如:

 RewriteRule ^/free_item.php$ https://www.example.com/shop/detail/${freeitems:%1}? [L] RewriteRule ^/item.php$ https://www.example.com/shop/detail/${items:%1}? [L] 

祝你好运 :)