Apache mod_rewrite RewriteRule 尽管有 L 标志,但仍会循环

Apache mod_rewrite RewriteRule 尽管有 L 标志,但仍会循环

Apache/2.4.54。
我试图实现类似的 URL(例如“/anystuff.htm”)在外部重定向到“/something”,而内部是“something.html”。但以下规则会导致循环而不是停止,即匹配“something”

RewriteEngine On
RewriteBase /
RewriteRule ^something$ something.html [L]
RewriteRule ^(some|thing|any|stuff).*/?$ /something [L, R=301,NC]

但看起来“L”指令没有效果,因为重定向到“/something”再次与第二条规则匹配,从而导致循环。

测试https://htaccess.madewithlove.com/表明它应该可以按预期工作。我认为我无法启用日志记录 :-(

答案1

L标志仅停止当前通过重写引擎的过程,而不会停止全部处理。后面的指令不会立即处理,但(在目录上下文中)重写过程会重新开始...在“第二遍”期间,第一条规则不再匹配(因为输入现在是something.html),但第二条规则匹配,因此触发重定向。

(重写引擎会有效地“循环”,直到 URL 保持不变。在以下情况下使用这些指令会更容易理解:服务器(非目录)上下文,其中L标志确实有效地停止了所有处理,因为重写引擎只有一次传递。)

然而,在 Apache 2.4 中END,你可以使用该标志来停止重写引擎的所有处理(在目录上下文)。例如:

RewriteEngine On

RewriteRule ^something$ something.html [END]
RewriteRule ^(some|thing|any|stuff) /something [R=301,NC,L]

(请注意,你输入的是错误的空间在第二条规则的 flags 参数中。这会导致解析错误,所以我认为这是你问题中的拼写错误?)

第二条规则(即.*/?$)的尾随正则表达式是多余的。

L与重定向(标志)一起使用R与 相同END。所有处理都停止。

RewriteBase您的示例中的指令是多余的。

注意:您应该先使用 302(临时)重定向进行测试,只有当您确认这可以正常工作时才更改为 301(永久)。浏览器会永久缓存 301,因此可能会使测试出现问题。因此,您需要在测试之前清除浏览器(以及任何中间)缓存。

测试https://htaccess.madewithlove.com/表明它应该可以按预期工作。

与真实服务器不同,MWL 测试器仅(有效地)对规则进行“一次传递”,因此无法检测重写/重定向循环。


在旁边:通常,你应该在内部重写之前安排外部重定向指令。但是,你的例子将重定向/something到其自身,因此您的两个指令当前取决于它们的顺序。

相关内容