【问题标题】:Htaccess conditional https for static pages静态页面的 Htaccess 条件 https
【发布时间】:2017-05-31 10:53:11
【问题描述】:

我的网站启用了 HTTPS,并且所有页面都使用 仅使用 HTTPS。客户现在需要将静态页面(如 about-us、termsofus)显示为 HTTP 页面而不是 HTTPS。这意味着即使用户尝试以 HTTPS 方式打开 about-us 页面,它也应该重定向到 about-us 的 HTTP 版本。

我的.htaccess代码如下:

Options -Indexes

<IfModule mod_rewrite.c>

RewriteEngine on
#RewriteCond %{HTTPS} off
#RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !^\/about-us
RewriteCond %{REQUEST_URI} !^\/termsofus
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTPS} on
RewriteCond %{REQUEST_URI} \/about-us [OR]
RewriteCond %{REQUEST_URI} \/termsofus
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
</IfModule>

问题:每当我打开 HTTP/HTTPS 版本的 about-us 页面时,它都会不断将我重定向到 index.php。 例如:https://example.com/about-us 到 https://example.com/index.php

本站使用 PHP YII 框架。

【问题讨论】:

    标签: php .htaccess yii


    【解决方案1】:

    使用THE_REQUEST 变量而不是REQUEST_URI。 THE_REQUEST 变量表示 Apache 从您的浏览器收到的原始请求,它在执行某些重写规则后不会被覆盖。

    Options -Indexes
    
    RewriteEngine on
    
    RewriteCond %{HTTPS} off
    RewriteCond %{THE_REQUEST} !\s/+(about-us|termsofus) [NC]
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
    
    RewriteCond %{HTTPS} on
    RewriteCond %{THE_REQUEST} \s/+(about-us|termsofus) [NC]
    RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.php
    

    确保在测试此更改之前清除浏览器缓存。

    【讨论】:

    • 谁能解释这一行的作用:RewriteCond %{THE_REQUEST} !\s/+(about-us|termsofus) [NC]
    • 这意味着原始请求不以/about-us和/termsofus开头
    【解决方案2】:

    anubhava 的回答已经解决了这个问题并提供了一个很好的解决方案。我想我只是参考您的原始代码就您陈述的示例发生的情况提供一些额外的解释:

    例如:https://example.com/about-us 到 https://example.com/index.php

    给定一个https://example.com/about-us的请求:

    1. 这符合您的第二条规则(HTTPS 为“开启”并且请求about-us)并重定向到http://example.com/about-us(即返回HTTP)。

    2. 重定向的请求(即http://example.com/about-us)现在匹配最后一条规则并被内部重写为index.php(前端控制器)。

    3. 但是,在每个目录 .htaccess 文件(directory 上下文)中,“重写的请求被交还给 URL 解析引擎”,并且该过程有效地重新开始。 REQUEST_URI 服务器变量也被更新以保存重写的 URL,即。 /index.php。

    4. 在第二次通过 .htaccess 文件时,请求(现在重写为 http://example.com/index.php)符合您的第一条规则(HTTPS 为“关闭”并且请求不是 /about-us 或 /termsofus)所以请求被重定向(第二次)到https://example.com/index.php。 (内部重写实际上更改为外部重定向。)

    5. 重定向的请求(现在为https://example.com/index.php)与.htaccess 文件中的任何规则都不匹配,因此原样通过。页面已投放。

    如果您检查网络流量,您应该会看到上面提到的两个外部重定向。

    另一种可能的解决方案是在最后一个RewriteRule 上使用END 标志(仅限Apache 2.4+)。这有效地结束 URL 重写过程,因此该过程在步骤#2 停止。虽然我仍然支持 anubhava 的解决方案并改为检查 THE_REQUEST,它适用于 Apache 2.2,并且如果您引入额外的重写,它仍然可以工作。

    【讨论】:

    • 谢谢,您的回答帮助我了解了我的代码出了什么问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多