我正在做一些应该非常简单但第二天就碰壁的事情。URL 重定向要求是:
- 非 www => www
- 非 https => https
/file.html
=>/utilities/template_handler.php?filename=file.html
问题:当我请求https://example.com/file.html
我得到 r=301 到
https://example.com/utilities/template_handler.php?filename=https://www.example.com/file.html
我的.htaccess
:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301]
RewriteRule ^(.*)\.html$ /utilities/template_handler.php?filename=$1.html [NC]
我正在使用 litespeed 网络服务器,但出于故障排除的目的,我也设置了 Apache,结果相同。打开调试后,我看到:
strip base: '/' from URI: '/file.html'
Rule: Match 'file.html' with pattern '.*', result: 1
Cond: Match 'on' with pattern 'off', result: -1
Rule: Match 'file.html' with pattern '.*', result: 1
Cond: Match 'domain.com' with pattern '^www\.', result: -1
Source URI: 'file.html' => Result URI: 'https://www.example.com/file.html'
Rule: Match 'https://www.example.com/file.html' with pattern '^(.*)\.html$', result: 2
Source URI: 'https://www.example.com/file.html' => Result URI: '/utilities/template_handler.php?filename=https://www.example.com/file.html'
replace current query string with 'filename=https://www.example.com/file.html'
如果我注释掉最后一条规则,我将正确处理前两个要求。
如果请求发送到非 www 或 www 但非 ssl,则会出现相同的错误。
您需要在这两个指令中包含
L
( ) 标志,否则,处理将继续通过文件,并且 URL 将被后面的指令进一步重写(使用前一个指令的输出)。并且由于前面的指令已经触发了外部重定向,因此您将在外部重定向到,而不是内部重写。last
RewriteRule
RewriteRule
/utilities/template_handler.php?filename=....
在请求表单的 URL 时,还应反转这些指令以避免不必要的双重重定向
http://example.com/...
。(特别是添加了L
标志。)例如:
另请注意,我已从否定条件中删除了
NC
标志。!^www\.
由于这是一个否定的正则表达式,因此您希望它在未启动时重定向www
- 全部小写。您仍然希望重定向表单的“错误”请求WwW
- 但如果您在NC
此处包含标志,它们不会。如果你愿意,你可以
L
在最后加入旗帜RewriteRule
——尽管这样做是个好习惯。它实际上是隐含的,因为无论如何它是最后一条规则,但是如果您添加了更多指令,那么您可能需要记住添加它。