Я хочу делать на своем веб-сайте три вещи:
www
в URL/*
к /index.php?p=*
(поскольку я использую фреймворк). (Или даже перенаправить "визуально" /index.php?p=*
к /*
, затем внутреннее перенаправление /*
к /index.php?p=*
...)Вот мой текущий .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule (.*) https://%1/$1 [R=301]
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+) index.php?p=$1 [QSA]
</IfModule>
Однако, когда я запускаю эту конфигурацию, мои перенаправления 301 не работают - точнее, код 301 фактически отправлено клиенту, но нет Location:
заголовок отправляется:
$ curl http://mywebsite.com/path -I
HTTP/1.1 301 Moved Permanently
Date: Thu, 23 Apr 2020 19:03:57 GMT
Server: Apache/2.4.38 (Debian)
Set-Cookie: ci_session=q24j0enjrskagec2fggi256bpg5fsvs6; expires=Thu, 23-Apr-2020 20:39:57 GMT; Max-Age=7200; path=/; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Type: text/html; charset=UTF-8
Если я попытаюсь поставить блок index.php
перед двумя другими, HTTPS и www
перенаправление работает, но Location:
header имеет странное поведение при работе со страницами:
λ curl http://mywebsite.com/fr/salon -I
HTTP/1.1 301 Moved Permanently
Date: Thu, 23 Apr 2020 19:09:03 GMT
Server: Apache/2.4.38 (Debian)
Location: https://mywebsite.com/fr/salon?p=fr/salon
Content-Type: text/html; charset=iso-8859-1
(Вы также можете увидеть, что кодировка изменилась по какой-то странной причине)
Какие изменения я должен внести в свои правила, чтобы три моих перенаправления работали?
Спасибо!
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] RewriteRule (.*) https://%1/$1 [R=301] RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
Вам не хватает L
(last
) на обоих ваших перенаправлениях. Без L
обработка флага продолжается и перехватывается следующей внутренней перезаписью.
Например:
RewriteRule (.*) https://%1/$1 [R=301,L]
ОБНОВИТЬ: Вы должны строго включать L
Отметьте также и вашу более позднюю перезапись. Хотя если это последний RewriteRule
в любом случае это не имеет особого значения. Однако, если вы позже добавите больше правил, это может быть важно.
Или даже перенаправить "визуально"
/index.php?p=*
к/*
Эта часть требуется только в том случае, если вы изменяете существующую структуру URL, где старый index.php?p=
URL-адрес индексируется поисковыми системами или ссылается на него третьими лицами.
Важным моментом здесь является предотвращение потенциального цикла перенаправления путем предотвращения перенаправления перезаписанного URL-адреса. Мы можем сделать это, проверив REDIRECT_STATUS
переменная окружения (которая пуста при первоначальном запросе и имеет значение «200», как в статусе HTTP 200 OK после первой успешной перезаписи).
Например, перед существующие перенаправления сразу после RewriteBase
директиве, вы можете сделать что-то вроде следующего для внешнего перенаправления /index.php?p=*
к /*
:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^p=([^&]*)
RewriteRule ^index\.php$ https://example.com/%1 [QSD,R=302,L]
В QSD
Флаг (Отмена строки запроса) (Apache 2.4+) необходим для удаления строки запроса (т.е. p=*
Параметр URL) из запроса. Это предполагает, что у вас нет других параметров URL, которые нужно передать - все они отбрасываются.
Это также предполагает, что p
Параметр URL-адреса всегда встречается в начале строки запроса (согласно вашей перезаписи).
Включив абсолютный URL в замена string мы избегаем любого вторичного перенаправления, связанного с запросом субдомена HTTP или www.
Обратите внимание, что в настоящее время это 302-е (временное) перенаправление. Желательно сначала протестировать с 302, прежде чем переходить на 301 (постоянное) перенаправление, чтобы избежать потенциальных проблем с кешированием.
RewriteEngine On RewriteCond %{HTTPS} off [OR] RewriteCond %{HTTP_HOST} ^www\. [NC] RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC] RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]