我的文件中有以下内容.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 不以斜杠结尾(如上所述),则上述规则(包括 URL 末尾的斜杠)条件模式)总是会成功(这是否定条件),因此重定向到 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
第一次成功重写(即 CodeIgniter 路由)后,环境变量设置为“200”。初始请求时未设置该变量(即-^$
空字符串)。
如果这仍然导致重定向,那么 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 的情况下运行?)