当我偶然发现这个问题时,我正在为 localhost 和 godaddy 构建 .htaccess。
RewriteEngine on
SetEnvIf HOST ^localhost$ LOCAL=/company
SetEnvIf HOST ^((?!localhost).)+ LOCAL=/
<If "%{ENV:LOCAL} == '/'">
RewriteRule (.+) index.php?test=godaddy [QSA,L]
</If>
<Else>
RewriteRule (.+) index.php?test=localhost [QSA,L]
</Else>
我曾尝试寻找答案,例如在里面添加 ifmodule mod_rewrite,也尝试封装 if 指令,但无济于事,想知道为什么这不起作用。
我确实发现,如果在 index.php 之前放置一个 /,它将返回到 localhost 的仪表板,而对于 godaddy,它将返回内部服务器错误。
答案1
表达式中使用 mod_rewrite 指令<If>
似乎存在很多“缺陷”*1毫无疑问与晚的处理指令的阶段。
(*1我不确定它是否真的有“缺陷”或者是“设计使然”,但它肯定是没有记录的、奇怪的并且没有帮助的!)
在一个<If>
块内RewriteRule
图案(即(.+)
)与请求映射到的完整绝对文件系统路径匹配,而不是相对(或根相对) URL 路径*2. 和相对路径替代(不以斜线或方案开头)与什么相关?!在测试(目录?)前缀在表达式中相对路径替换中添加的文本<If>
是文字文本*If/
- 这很奇怪。而且这不管语境(.htaccess
,目录,虚拟主机或者服务器)。
(*2 这已被报告为一个错误,尽管我不确定是否真的如此。我以为我看到了比我链接到的更详细/讨论更深入的错误报告,但我似乎找不到它?)
因此,在您的情况下,“错误请求”是由于内部重写而导致的*If/index.php?test=...
。
我确实发现,如果你在它返回到 localhost 和 godaddy 的仪表板
/
之前放置一个,它将返回一个内部服务器错误。index.php
斜杠前缀将导致相对于文档根目录的 URL 路径。
我会预计这会导致内部重写循环(即 500 内部服务器错误响应),因为重写引擎在请求首次重写后重新启动,并且没有什么可以阻止这种情况反复发生。不确定 localhost 和 GoDaddy 之间的行为差异,除了可能与您可能拥有的其他指令交互的方式之外?
因此,如果可能的话,我会避免在<If>
表达式中使用 mod_rewrite 指令。(在这个有限的例子中,<If>
表达式当然是不必要的。)
然而,有更好的方法来解决这个问题。
假设您在“localhost”上可以访问服务器配置/VirtualHost?在这种情况下,使用 Apache 参数/变量会更容易Define
。例如:
# In <VirtualHost> on local development server
Define LOCAL 1
然后在.htaccess
:
RewriteEngine on
# Local Development Server
<IfDefine LOCAL>
RewriteCond %{QUERY_STRING} !^test
RewriteRule (.+) index.php?test=localhost [QSA,L]
</IfDefine>
# Live Server
<IfDefine !LOCAL>
RewriteCond %{QUERY_STRING} !^test
RewriteRule (.+) index.php?test=godaddy [QSA,L]
</IfDefine>
在旁边:捕获RewriteRule
图案上述指令完全是多余的。
也可以看看我的答案StackOverflow 上的相关问题强调了在 Apache<If>
表达式中使用 mod_rewrite 的其他问题: