htaccess 使用完整 URL 重定向非 www 和 HTTP

htaccess 使用完整 URL 重定向非 www 和 HTTP

我有这些.htaccess规则:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST} [R=301,L]

在主域上将 HTTP 重定向到 HTTPS 并将非 www 重定向到 www 时,它工作正常,但如果用户直接转到特定 URL,我希望使用完整的 URL 路径重定向到 https、www。

例如:

  • http://example.com/login应该重定向到https://www.example.com/login
  • http://www.example.com/login应该重定向到https://www.example.com/login
  • https://example.com/login应该重定向到https://www.example.com/login

使用当前设置,它只会重定向到https://www.example.comhttps://www.example.com/index.php,我该如何实现?

答案1

正如@GeraldSchneider 在评论中提到的那样,您的指令顺序错误。外部重定向(HTTP 到 HTTPS 和非 www 到 www)需要转你的前端控制器,否则它们将永远不会被处理,除了实际的文件请求。(你的前端控制器将所有未知请求路由到,index.php然后停止

但是,您的重定向也是不正确的。您缺少来自代换,因此它们总是会重定向回文档根目录。

因此,请尝试以下操作:

RewriteEngine On

# Front-controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

# HTTP to HTTPS redirect
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]

# Non-www to www redirect
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [R=301,L]

关于上述指令的说明:

  • (.*)在前端控制器中,如果 URL 路径(即)没有被使用,则无需捕获它。代换QSA这里也不需要标志 - 默认情况下会附加来自请求的查询字符串。
  • $1请注意RewriteRule 替代- 这是对从请求中捕获的 URL 路径的反向引用(即“完整 URL”)。这在您的两次重定向中都缺失。
  • 您缺少[R=301,L]从 HTTP 到 HTTPS 重定向的标志。如果不明确说明状态代码,这将导致临时 302 重定向,并且重写将继续。如果您打算稍后实施 HSTS,则这些重定向需要分开。

但是,如果您有权访问服务器配置并且不打算实施 HSTS,那么请参考@HBruijn 的回答。

答案2

理想情况下,您可以访问服务器配置,然后您不需要从文件进行重定向.htaccess,而您的重定向将成为教科书案例在配置特定 VirtualHost 条目上的重定向时,何时不使用 mod_rewrite。

<VirtualHost *:80>
   # Redirect http://[www.]example.com/login to https://www.example.com/login
    ServerName www.example.com
    ServerAlias example.com
    Redirect "/" "https://www.example.com/"
</VirtualHost>


<VirtualHost *:443>
    # Redirect https://example.com/login to https://www.example.com/login
    ServerName example.com
    Redirect "/" "https://www.example.com/"
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    DocumentRoot /var/www/...
    ....
</VirtualHost>

相关内容