5

我正在codeigniter中建立一个站点。我在 .htaccess 文件中有一系列重写条件和规则。第一组规则根据 uri 的第一段打开或关闭 SSL。

然后它再次循环,如果找到匹配项,则适当地重定向页面。如果不匹配,并且 uri 不以列出的任何字符串开头,它会将您重定向到另一个页面。如果不满足任何条件,则转到索引页面。

问题在于我的第一组打开和关闭 SSL 的规则。我想指定 uri 必须以管理员或安全方式开始。但是,如果我将 ^ 添加到字符串的开头,一切都会中断。这是我所拥有的:

RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/?(admin|secure)
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{HTTPS} on 
RewriteCond %{REQUEST_URI} !^/?(admin|secure)
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]

...specific rewrites here
RewriteRule ^secure-form1$ secure/contract/secure-form1 [L]
RewriteRule ^secure$ secure/article/secure [L]

RewriteCond %{HTTP_HOST} ^www.example.com$ 
RewriteCond %{REQUEST_URI} !^/(admin|form|secure|page)/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/page/article/$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]

如果我在前 2 个重写条件(https 开启和关闭)中保留 ^ 符号,则 http://www.example.com/secure 重写为 https://www.example.com/index.php/secure/article/安全 ,这是最后的重写规则。url 实际上在浏览器中更改为此。

如果我从前 2 个重写条件中取出 ^ 符号,那么它会转到正确的页面。但我确实需要指定 uri 的开头,因为在 uri 中间(并在斜线后面)有其他页面不应该使用 SSL。

我想不通这个。

4

2 回答 2

11

试试这个:

RewriteCond %{HTTPS} off 
RewriteCond %{HTTP_HOST} ^(.*)$ 
RewriteRule ^/?(admin|secure)$ https://%1/$1 [R=301,L]
于 2012-09-17T19:53:31.983 回答
8

老问题,我知道,但如果你真的想坚持这个%{REQUEST_URI}条件,还有另一种解决方案可能会更好:

RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} ^/?(admin|secure)$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

与 OP 的主要区别在于包含/?检查 URI 开头是否存在正斜杠。AFAIK,不同的 Apache 安装可能会或可能不会在%{REQUEST_URI}.

这样做的一个好处是您可以将规则应用于多个条件:

RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} ^/?admin$ [OR]
RewriteCond %{REQUEST_URI} ^/?secure$ [OR]
RewriteCond %{REQUEST_URI} ^/?top-secret$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

就我认为的方式而言,这比一长串以管道分隔的字符串更容易使用。与单个正则表达式相比,这是以潜在的效率损失为代价的,但是您可以进行一些其他改进来抵消这一点:

  • 使用lexographically equal operator !=on。如果您只是使用off它,它会被视为正则表达式。

  • 消除 RewriteRule 模式,将其替换为单个插入符号,然后使用环境 vars%{HTTP_HOST}%{REQUEST_URI}. 这节省了更长的正则表达式模式以及反向引用的开销。

于 2014-01-09T18:04:42.363 回答