htaccess取代了完整的URL而不是REQUEST_URI

我正在做一些应该很简单的事情,但是第二天就会碰壁。 urlredirect要求是:

  • 非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 web服务器,但为了解决故障的目的也设置了Apache,结果也是一样。 打开debugging后,我看到:

 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,同样的错误。

 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指令中包含Llast )标志,否则,将继续处理整个文件,URL将由RewriteRule (使用前一个指令的输出)进一步重写。 而且由于外部redirect已经被前面的指令触发了,你可以从外部redirect/utilities/template_handler.php?filename=.... ,而不是内部重写

这些指令也应该颠倒,以避免在请求http://example.com/...forms的URL时发生不必要的双重redirect。 (特别是增加了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] 

另外请注意,我已经从否定!^www\.删除了NC标志!^www\. 条件。 由于这是一个否定的正则expression式,所以当它不启动www – 全部为小写时,您希望它redirect。 你仍然希望WwW “坏”请求被redirect – 但是如果你在这里包含NC标志,他们将不会。

如果你愿意的话,你可以在最后一个RewriteRule包含L标志 – 尽pipe这样做是一个好习惯。 这是有效的暗示,因为它是最后一个规则,但是如果你添加了更多的指令,那么你可能需要记住添加它。