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

htaccess для выполнения определенных перезаписей на разных uri

У меня в моем .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.

# Prevent /sns from using https but this DOES need codeigniter rewriting (see below)
RewriteCond %{REQUEST_URI} !^/(sns)/

Если URL-адрес запроса не заканчивается косой чертой (как указано), то приведенное выше правило (которое включает конечную косую черту на CondPattern) всегда будет успешным (это отрицается условие), поэтому перенаправление на HTTPS будет происходить всегда.

В идеале вы должны канонизировать завершающую косую черту раньше в запросе. Либо включить косую черту в конце, либо нет (в противном случае, по сути, дублированный контент и потенциально может вызвать проблемы с другими скриптами, анализирующими URL-адрес).

Однако для обработки двух URL-адресов /sns и /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?)