Назад | Перейти на главную страницу

htaccess перенаправляет без www и HTTP с полным URL

У меня есть эти .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-путем.

Например:

При текущих настройках перенаправляется только на 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]

Примечания относительно вышеуказанных директив:

  • Во фронт-контроллере нет необходимости захватывать URL-путь (т.е. (.*)), если он не используется в замена. В 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>