我正在使用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 on& off),那么 http://www.example.com/secure 重写为 https://www.example.com/index.php/secure/article/secure 这是最后一次重写规则。该URL实际上在浏览器中更改为此。
如果我从前两个重写条件中取出^符号,那么它将转到右侧页面。但是我确实需要指定uri的开头,因为在uri的中间(并且在斜线下面)有其他页面具有“安全”,不应该使用SSL。
我无法想出这个。
答案 0 :(得分:8)
试试这个:
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(.*)$
RewriteRule ^/?(admin|secure)$ https://%1/$1 [R=301,L]
答案 1 :(得分:6)
老问题,我知道,但是如果你真的想要坚持%{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]
对于我的想法,这比使用管道分隔的长串字符串更容易使用。这是以潜在的效率损失为代价而不是单个正则表达式,但是您可以做出一些其他改进来抵消这一点:
使用词汇相等的运算符!=on
。如果您只使用off
,则会将其视为正则表达式。
消除RewriteRule模式,将其替换为单个插入符号,然后使用环境变量%{HTTP_HOST}
和%{REQUEST_URI}
。这节省了较长的正则表达式模式以及backrefs的开销。