【问题标题】:How to selectively redirect to https/http如何选择性地重定向到 https/http
【发布时间】:2014-08-09 13:34:31
【问题描述】:

我需要将站点中的一些页面合并到 https。现在我想要以下两种情况。

  1. 如果页面 REQUEST_URI 是用户、用户/登录、用户/注册、购物车、结帐并且原始协议是 http。应该会重定向到 https。
  2. 如果页面 REQUEST_URI 不是用户、用户/登录、用户/注册、购物车、结帐且原始协议为 https。应该会重定向到 http。

所以我实施了以下规则。

# Block 1 - Forcing HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80

# Forcing HTTPS
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} ^/cart  [OR]
RewriteCond %{REQUEST_URI} ^/checkout  [OR]
RewriteCond %{REQUEST_URI} ^/user/login [OR]
RewriteCond %{REQUEST_URI} ^/user [OR]
RewriteCond %{REQUEST_URI} ^/user/register
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,L]


# Block 2 - Forcing HTTP
RewriteCond %{HTTPS} !=off [OR]
RewriteCond %{SERVER_PORT} 443

RewriteCond %{SERVER_PORT} !^80$
RewriteCond %{REQUEST_URI} !^/cart 
RewriteCond %{REQUEST_URI} !^/checkout 
RewriteCond %{REQUEST_URI} !^/user/login
RewriteCond %{REQUEST_URI} !^/user
RewriteCond %{REQUEST_URI} !^/user/register
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,L]


# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# The following rewrites all other queries to index.php. The 
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to 
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size 
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]

这里我遇到了问题,如果启用了两个块之一,则功能会根据规则顺利运行。但如果两者都启用,递归重定向开始发生。我需要这两种功能。如果可以通过 .htaccess 规则?

更新:在 SO 上提出的类似问题为 how in htaccess can i redirect the user to https from http and back again 。但它只有一个答案建议移到应用程序方面。

更新 2:添加 Zend Framework 应用程序默认的 .htaccess 规则

【问题讨论】:

    标签: apache .htaccess redirect https rewrite


    【解决方案1】:

    你把它弄得很复杂。像这样简化你的规则:

    RewriteEngine On
    
    # Block 1 - Forcing HTTPS
    RewriteCond %{HTTPS} off [OR]
    RewriteCond %{SERVER_PORT} 80
    RewriteRule ^(cart|checkout|user|user/login|user/register)/?$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,NE,L]
    
    # Block 2 - Forcing HTTP
    RewriteCond %{HTTPS} on [OR]
    RewriteCond %{SERVER_PORT} 443
    RewriteRule !^(cart|checkout|user|user/login|user/register)/?$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,NC,NE,L]
    

    确保在新浏览器中进行测试以避免 301 缓存问题。

    【讨论】:

    • 实际上我无法控制可以构建的其他 URI,例如用户/详细信息、用户/信息、购物车/新,可能/可能不是 https 页面。所以我需要使用 RewriteCond 匹配确切的开始。使用 (cart|checkout|user) 也会使用其他 url。
    • 但是您在第一条规则中有RewriteCond %{REQUEST_URI} ^/user [OR] 将强制所有以/user 开头的URI 使用https
    • 嗯,我可能很快会在末尾添加“$”。由于需要精确的 url 匹配。
    • 面临奇怪的问题。 https 到 http 部分(强制 http)正常。但是 http 到 https 部分(强制 https)重定向到 index.php。我无法控制这一点。 (因为应用程序(Zend Framework 2)已经有将所有请求重定向到 index.php 的规则)。请参阅应用程序默认 .htaccess 部分的更新
    • 这意味着您还有其他一些规则/代码问题,因为输入 https://domain.com/cart 不会使我建议的两个规则都执行。
    猜你喜欢
    • 1970-01-01
    • 2011-12-07
    • 2015-04-23
    • 2010-09-05
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    相关资源
    最近更新 更多