我正在做一些本来应该很简单的事情,但第二天就遇到了麻烦。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 webserver,但为了排除故障,我也设置了 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,则会出现同样的错误。
答案1
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]
您需要在这两个指令上都包含L
( ) 标志,否则,处理将继续通过文件,并且 URL 将由后面的指令进一步重写(使用上一个指令的输出)。由于前面的指令已经触发了外部重定向,因此您将获得last
RewriteRule
RewriteRule
外部重定向/utilities/template_handler.php?filename=....
而不是内部重写。
这些指令也应该被反转,以避免在请求表单的URL时出现不必要的双重重定向http://example.com/...
。(特别是添加了标志之后L
。)
例如:
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
还要注意,我已从NC
否定!^www\.
条件中删除了标志。由于这是否定regex,您希望它在未启动时重定向- 全部小写。您仍然希望重定向www
表单的“坏”请求- 但如果您在此处包含标志,则不会重定向。WwW
NC
如果您愿意,您可以L
在最后添加标志RewriteRule
- 尽管这样做是很好的做法。这实际上是隐含的,因为它无论如何都是最后一条规则,但如果您添加了更多指令,那么您可能需要记住添加它。