【发布时间】:2012-02-27 12:34:04
【问题描述】:
许多发帖人在调试他们的 .htaccess 文件中的 RewriteRule 和 RewriteCond 语句时遇到问题。其中大多数使用共享托管服务,因此无权访问根服务器配置。正如许多受访者所建议的那样,他们无法避免使用.htaccess 文件进行重写,并且无法启用 RewriteLogLevel”。此外,还有许多.htaccess 特有的陷阱和约束没有得到很好的覆盖。设置一个对于大多数人来说,本地测试 LAMP 堆栈涉及太多的学习曲线。
所以我的问题是我们如何建议他们调试他们的规则他们自己。我在下面提供一些建议。其他建议将不胜感激。
-
了解 mod_rewrite 引擎会循环遍历
.htaccess文件。引擎运行这个循环:do execute server and vhost rewrites (in the Apache Virtual Host Config) find the lowest "Per Dir" .htaccess file on the file path with rewrites enabled if found(.htaccess) execute .htaccess rewrites (in the user's directory) while rewrite occurred因此,您的规则将被重复执行,如果您更改 URI 路径,那么它可能最终会执行其他
.htaccessfiles(如果存在)。因此,请确保终止此循环,如有必要,通过添加额外的RewriteCond来停止规则触发。同时删除任何较低级别的.htaccess重写规则集,除非明确打算使用多级规则集。 -
通过针对一组测试模式进行测试,确保每个 Regexp 的语法正确,以确保它是有效的语法,并且可以使用完整的测试 URI 实现您想要的。详情请见answer below。
-
在测试目录中逐步建立规则。您可以利用“在路径上执行最深的
.htaccess文件功能”来设置单独的测试目录(树)和在此处调试规则集,而不会破坏您的主要规则并停止您的站点工作。您必须一次添加一个,因为这是将故障定位到单个规则的唯一方法。 -
使用虚拟脚本存根转储服务器和环境变量。 (参见清单 2)如果您的应用程序使用
blog/index.php,那么您可以将其复制到test/blog/index.php并使用它在test子目录中测试您的博客规则。您还可以使用环境变量来确保重写引擎正确解释替换字符串,例如RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]并在 phpinfo 转储中查找这些 REDIRECT_* 变量。顺便说一句,我使用了这个并在我的网站上发现我必须使用
%{ENV:DOCUMENT_ROOT_REAL}。在重定向器循环的情况下,REDIRECT_REDIRECT_* 变量会列出前一次传递。等等。 -
确保您不会被浏览器缓存不正确的 301 重定向所困扰。见answer below。我感谢Ulrich Palha。
-
重写引擎似乎对
.htaccess上下文中的级联规则很敏感(这是RewriteRule导致替换的地方,但这属于进一步的规则),因为我发现了内部子请求的错误@987654324 @,以及不正确的 PATH_INFO 处理,通常可以通过使用 [NS]、[L] 和 [PT] 标志来防止。
还有什么意见或建议吗?
清单 1 -- phpinfo
<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);
【问题讨论】:
-
这些很好...也许您应该将它们从问题移到答案中。
-
@w00t,我已根据您的建议拆分了正则表达式检查器,因为我想通过链接在其他答案中引用它。
-
您可能希望将the control flow diagram from the docs 添加到您的第一个建议中。 IMO 它比任何伪代码或解释都更容易理解,这确实是 mod-rewrite 巫术中最黑暗的部分。
-
6 号是一笔大买卖。重写标准 apache 配置文件与 .htaccess 文件中行为不同的规则必须吸引很多人。
-
在这些提示中可能值得添加的东西:我花了一些时间调试它重定向而不是重写的问题。事实证明,当我想要“/comment/”时,我将它重写为“/comment”。它正在重写到“/comment”,然后服务器正在重定向到“/comment/”。对于那些习惯于 Apache 的人来说,这种行为很明显,但对于像我这样的新手来说可能就不那么明显了。
标签: apache .htaccess mod-rewrite