В моем досье есть следующее .htaccess
:
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
# Block hidden directories
RewriteRule "(^|/)\." - [F]
# Prevent /health_check.php from using https
RewriteCond %{REQUEST_URI} !(health_check\.php)$
# Prevent /sns from using https but this DOES need codeigniter rewriting (see below)
RewriteCond %{REQUEST_URI} !^/(sns)/
# Reroute http to https
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
# Prevent rewriting of domain for codeigniter
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
</IfModule>
Вроде бы все работает нормально, кроме этой /sns
части. Я не могу заставить это прекратить перенаправление на https.
Я бы хотел http://sub.example.com/sns
и http://sub.example.com/health_check.php
не перенаправлять на https.
решение1
# Prevent /sns from using https but this DOES need codeigniter rewriting (see below) RewriteCond %{REQUEST_URI} !^/(sns)/
Если URL-адрес запроса не заканчивается косой чертой (как указано), то применяется указанное выше правило (которое включает косую черту в концеCondPattern) всегда будет успешным (этоотрицаетсяусловие), поэтому перенаправление на HTTPS будет происходить всегда.
В идеале, вы должны канонизировать завершающий слеш ранее в запросе. Либо включайте завершающий слеш, либо нет (иначе это по сутидублированный контенти потенциально может вызвать проблемы с другими скриптами, анализирующими URL).
/sns
Однако для обработки двух URL-адресов /sns/
вам необходимо сделать завершающий слеш необязательным и включить якорь конца строки ( ^
). Например:
RewriteCond %{REQUEST_URI} !^/sns/?$
Обратите внимание, что это соответствует только двум указанным URL. Это не будет соответствовать URL в форме /sns/<something>
.
Я удалил скобки вокруг сегмента пути (вам также следует удалить другие скобки в вашем регулярном выражении). Это создает захваченную группу и является излишним в директивах, которые вы опубликовали.
ОБНОВЛЯТЬ:Вам также понадобится дополнительная проверка, чтобы убедиться, что переписанный URL (т. е. /index.php/sns
) не перенаправлен. Вы можете сделать это более общим способом, применив перенаправление HTTPS только к первоначальному запросу, а не к переписанному запросу, включив дополнительное условие:
# Only applies to direct requests (not rewritten requests)
RewriteCond {%ENV:REDIRECT_STATUS} ^$
Переменная окружения REDIRECT_STATUS
устанавливается на "200" после первой успешной перезаписи (т.е. маршрутизации CodeIgniter). Она не устанавливается при первоначальном запросе (т.е. ^$
- пустая строка).
Если это все еще приводит к перенаправлению, то, возможно, сам CodeIgniter инициирует перенаправление (после .htaccess
обработки).
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
В стороне:И как отмечено в моем комментарии, вам следует удалить ./
префиксRewriteRule
замена. Смотритеконец моего ответанаэтот вопрос StackOverflowдля объяснения.
Краткое содержание
Options +FollowSymlinks
RewriteEngine On
# Block hidden directories
RewriteRule ^\. - [F]
# Only applies to direct requests (not rewritten requests)
RewriteCond {%ENV:REDIRECT_STATUS} ^$
# Prevent /health_check.php from using https
RewriteCond %{REQUEST_URI} !health_check\.php$
# Prevent /sns from using https but this DOES need codeigniter rewriting (see below)
RewriteCond %{REQUEST_URI} !^/sns/?$
# Reroute http to https
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Prevent rewriting of domain for codeigniter
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
Перенаправление с HTTP на HTTPS в конечном итоге должно быть 301 (постоянным) перенаправлением, но только после того, как вы убедитесь, что оно работает нормально. Флаг R
сам по себе по умолчанию имеет значение 302 (временное) перенаправление.
(Вам также не нужна оболочка <IfModule>
, если только ваш сайт не предназначен для работы без mod_rewrite?)