这些规则:
RewriteEngine On
RewriteRule ^([^/]*)$ /index.php?page=$1 [L]
导致内部重写循环。重写引擎循环遍历所有规则,直到达到内部重定向限制(从而导致 500 服务器错误)或从引擎出来的结果 URI 与进入它的 URI 相同。此外(这是一个非常重要的概念),在将 URI 的前导斜杠发送到 htaccess 文件中的规则的重写引擎之前,它会被删除。所以在这里我们有:
- 提出请求:http ://domain.com/blah
- URI = /废话
- 去掉前导斜杠,URI = blah
- blah匹配
^([^/]*)$
,应用规则,URI = /index.php?page=blah
- 废话不等于/index.php
- 规则循环,URI = /index.php
- 去除前导斜杠,URI = index.php
- index.php匹配
^([^/]*)$
,应用规则,URI = /index.php?page=index.php
- 索引不等于/index.php
- 规则循环,URI = /index.php
- 去除前导斜杠,URI = index.php
- index.php匹配
^([^/]*)$
,应用规则,URI = /index.php?page=index.php
- 索引不等于/index.php
等等
你有几个选择来处理这个问题。最简单的方法是简单地/
从您的目标中删除:
RewriteRule ^([^/]*)$ index.php?page=$1 [L]
这将使得在上面的步骤 9 中,索引将等于index.php,从而停止重写过程(在第二次应用之前)。唯一的缺点是如果您需要重定向,或者如果 htaccess 文件被移动,目标中的相对 URI 有时会被误认为是文件路径而不是 URL 路径(apache 猜测这个,有时 apache 猜测错误的)。这可以通过包含一个基础来解决:
RewriteBase /
RewriteRule ^([^/]*)$ index.php?page=$1 [L]
您还可以添加条件以使其指向现有资源的 URL 将从应用中排除此规则:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)$ /index.php?page=$1 [L]
因此,如果 URI 指向现有文件或目录,则跳过该规则。因此,在 URI 变为/index.php时第一次重写后,由于该文件存在,因此第二次跳过该规则。这也使得对文档根目录中的图像、css、脚本或静态页面的请求不会通过index.php
. 如果这不是您想要的,如果 URI 已经是 index.php,您也可以直接跳过:
RewriteCond %{REQUEST_URI} !^/index.php
RewriteRule ^([^/]*)$ /index.php?page=$1 [L]