htaccess 文件对不同的 uri 进行特定的重写

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。

答案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 的情况下运行?)

相关内容