htaccess 替换完整 URL 而不是 REQUEST_URI

htaccess 替换完整 URL 而不是 REQUEST_URI

我正在做一些本来应该很简单的事情,但第二天就遇到了麻烦。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 将由后面的指令进一步重写(使用上一个指令的输出)。由于前面的指令已经触发了外部重定向,因此您将获得lastRewriteRuleRewriteRule外部重定向/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表单的“坏”请求- 但如果您在此处包含标志,则不会重定向。WwWNC

如果您愿意,您可以L在最后添加标志RewriteRule- 尽管这样做是很好的做法。这实际上是隐含的,因为它无论如何都是最后一条规则,但如果您添加了更多指令,那么您可能需要记住添加它。

相关内容