У меня есть эти .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-адрес, я хочу перенаправить на https, www с полным URL-путем.
Например:
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.com
или https://www.example.com/index.php
, как я могу этого добиться?
Как упоминал @GeraldSchneider в комментариях, ваши директивы находятся в неправильном порядке. В внешние перенаправления (HTTP на HTTPS и без www на www) нужно перейти перед ваш фронт-контроллер, поскольку в противном случае они просто никогда не будут обрабатываться ни для чего, кроме фактических запросов файлов. (Ваш фронт-контроллер направляет все неизвестные запросы на index.php
а потом останавливается.)
Однако ваши перенаправления также неверны. Вам не хватает "полного URL" из замена, так что в существующем виде они всегда будут перенаправлять обратно в корень документа.
Итак, попробуйте вместо этого что-то вроде следующего:
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]
Примечания относительно вышеуказанных директив:
(.*)
), если он не используется в замена. В QSA
Флаг здесь также не требуется - строка запроса из запроса добавляется по умолчанию.$1
в RewriteRule
учреждение - это обратная ссылка на захваченный URL-путь из запроса (то есть «полный URL»). Этого не было в обоих ваших перенаправлениях.[R=301,L]
флаги перенаправления HTTP на HTTPS. Без явного указания кода состояния это привело бы к временному перенаправлению 302, и перезапись продолжилась бы. Если вы собираетесь реализовать HSTS позже, эти перенаправления должны быть отдельными.Однако, если у вас есть доступ к конфигурации сервера и вы не собираетесь внедрять HSTS, вместо этого обратитесь к ответу @ HBruijn.
В идеале у вас есть доступ к конфигурации сервера, и тогда вам не нужно выполнять перенаправления с .htaccess
файл, и ваш становится чехол для учебников когда НЕ использовать mod_rewrite, когда вы настраиваете перенаправления для определенных записей VirtualHost.
<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>