虽然@Corey Henderson 所说的一切都非常有道理.. 它并不是 100% 符合现实。
在你的 .htaccess 中只有这 2 条规则(我知道,这是一个有点愚蠢的例子,但在进行复杂的重写时你最终可能会遇到同样的效果):
RewriteEngine On
RewriteRule (.*) /index.php?u=$1 [L]
你会想——将所有请求重定向到index.php。标志[L] 已设置,因此无需担心。好吧 - 显然这是值得担心的事情,因为在看到 [L] 标志 mod_rewrite 进入下一次迭代(进入循环)之后。因为我们有将始终执行的规则,所以我们将有无限循环(嗯,Apache 配置中有控制它的设置——默认情况下它最多 10 次迭代)。如果超出限制,那么您将看到 500 服务器错误消息,并且 Apache 的 error.log 中有这一行:“由于可能的配置错误,请求超出了 10 个内部重定向的限制。如有必要,请使用“LimitInternalRecursion”来增加限制。使用 'LogLevel debug' 获取回溯。”
如果出现以下情况,重写将停止:
- 无需处理更多规则
- 外部重定向
[R=301]
- 给出了明确的“无需重写”命令(
RewriteRule 的第二个参数——目标应为-。
- 重写到与迭代开始时完全相同的 URL 时。
- 已经提到“请求超出了 xx 个内部重定向的限制”。
所以是的.. 越快的重写迭代将被中断(规则在顶部)越好。
在排序规则时(当您有很多规则时,而不仅仅是 1-2-3),您可能会考虑以下逻辑(哪些规则在最上面):
- 在任何情况下您都不想接触的文件/文件夹的规则(按原样处理请求,无论域/协议如何)
- 改变域(例如重定向到
www.)或协议(强制HTTPS)的规则——你越快越好(好像你做得太晚了,它可能已经将URL从“nice " 真实)。
- 其他可能影响现有文件/文件夹的重要规则
- (考虑这样做)现有文件/文件夹“无需重写”(见下文,#1,但所有现有资源)
- 其他规则
- 抓住所有规则。
在重写 URL 的绝大多数网站上,您不会有超过 5-6 条规则(我见过的大多数 PHP 框架的默认 .htaccess 文件 + 像 WordPress 之类的一些产品只是“包罗万象”(如果文件/文件夹不存在然后重写请求到 index.php))。
每个网站都有自己的逻辑,所以上面的列表只是一个一般性的建议,仅此而已。
# Do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
我的主要观点是:如果您有很多规则,请考虑在某处插入这种“无需重写”以完全停止迭代。