RewriteCond REQUEST_URI - ^不能按预期工作

use*_*830 3 regex mod-rewrite codeigniter

我正在使用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]
Run Code Online (Sandbox Code Playgroud)

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

如果我从前两个重写条件中取出^符号,那么它将转到右页.但是我确实需要指定uri的开头,因为在uri的中间(并且在斜杠之后)有其他页面具有"安全",不应该使用SSL.

我无法想出这个.

Ωme*_*ega 8

试试这个:

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


njb*_*air 7

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

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

与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]
Run Code Online (Sandbox Code Playgroud)

对于我认为的方式,这比一长串管道分隔的字符串更容易使用.与单个正则表达式相比,这可能会导致潜在的效率损失,但您可以通过其他一些改进来抵消这一点:

  • 使用词汇相等的运算符!=on.如果你只是使用off它被视为正则表达式.

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