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

Обработка переадресации 301 и внутренней перезаписи в .htaccess

Я хочу делать на своем веб-сайте три вещи:

Вот мой текущий .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]