我有以下 htaccess 规则,它可以实现我想要的功能:它将任何请求重写到 index.php。但是,我可以让它独立于部分https://subsub.sub
吗?
RewriteRule ^(.*)$ https://subsub.sub.domain.example/index.php [L]
我想要类似的东西
RewriteRule ^(.*\.domain\.example)$ $1/index.php [L]
或者甚至像这样:
RewriteRule ^(.*)$ "%{HTTP_HOST}/index.php" [L]
(编辑:我期望HTTP_HOST
在哪里https://subsub.sub.domain.example
)
但是,这不起作用。这两种方法都会导致 500 错误。
编辑:Apache 错误日志:
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
但是,我无法在 htaccess 文件中设置 LogLevel。如何才能在共享主机上有效地调试此问题?
答案1
RewriteRule ^(.*)$ https://subsub.sub.domain.example/index.php [L]
这将导致外部 302(临时)重定向,而不是您所说的“重写”。隐含的重定向因为替换中的绝对 URL(方案 + 主机名)而发生。
然而,这本身似乎会导致重定向循环*1,所以想必你有一些先验状况(即RewriteCond
指令)来防止这种情况发生?
(*1除非您要重定向到一个完全不同的文件系统?虽然您的问题中没有提到这一点。)
RewriteRule ^(.*\.domain\.example)$ $1/index.php [L]
您无法将主机名与RewriteRule
图案。 这RewriteRule
图案仅匹配 URL 路径。要匹配请求的主机名,您需要一个RewriteCond
针对HTTP_HOST
服务器变量进行检查的指令。
RewriteRule ^(.*)$ "%{HTTP_HOST}/index.php" [L]
服务器HTTP_HOST
变量仅包含主机名(即 HTTP 请求标头的值Host
,因此名称为HTTP_HOST
)。换句话说,HTTP_HOST
将包含subsub.sub.domain.example
您的示例中的内容。因此,您的指令缺少https://
您需要手动添加到替换字符串前缀的方案,例如"https://%{HTTP_HOST}/index.php"
。没有方案,它将被视为相对 URL,并且没有R
( redirect
) 标志,会触发“内部重定向”(也称为“重写”) - 因此会报告错误。
到外部重定向所有请求都/index.php
在同一主机/域上,当请求形式为*.domain.example
(其中*
是任何子域)的主机名时,那么您需要执行以下操作:
RewriteCond %{HTTP_HOST} \.domain\.example$ [NC]
RewriteRule ^ /index.php [R,L]
如果你只是想重定向到相同的请求中的主机名。(假设UseCanonicalName On
未在服务器配置中设置 - 这不是默认设置。)
不需要捕获/详细^(.*)$
正则表达式,效率较低。你只是匹配所有内容,而不是在代换. 或者使用类似以下模式.?
来匹配任何事物反而。
正如我在回答开始时提到的那样,这确实假设您已经有其他可以防止重定向循环的条件。