Mod rewrite 带外部重定向和内部重写的mod_重写

Mod rewrite 带外部重定向和内部重写的mod_重写,mod-rewrite,redirect,ssl,Mod Rewrite,Redirect,Ssl,我正在尝试使用mod_rewrite重定向某些页面以使用SSL。为此,我有: RewriteCond %{SERVER_PORT} ^443$ RewriteCond %{REQUEST_URI} !^/login(\.php)?$ [NC] RewriteCond %{REQUEST_URI} !^/contact-us(\.php)?$ [NC] RewriteCond %{REQUEST_URI} !^/\..*$ RewriteRule ^(.*)$ http://www.example

我正在尝试使用mod_rewrite重定向某些页面以使用SSL。为此,我有:

RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^/login(\.php)?$ [NC]
RewriteCond %{REQUEST_URI} !^/contact-us(\.php)?$ [NC]
RewriteCond %{REQUEST_URI} !^/\..*$
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

RewriteCond %{HTTP_HOST} !^dev\.example\.com$ [NC]
RewriteCond %{SERVER_PORT} ^80$
RewriteCond %{REQUEST_URI} ^/login(\.php)?$ [NC,OR]
RewriteCond %{REQUEST_URI} ^/contact-us(\.php)?$ [NC]
RewriteRule ^(.+)\.php$ https://www.example.com/$1 [R=301,L]
这很好用,而且完全符合我的要求

稍后在我的.htace中,我有一个:

RewriteRule ^members/(.+)/change-password$ members/.change-password.php?item=$1 [NC,QSA,L]
因此,如果URL显示为,例如:

http://www.example.com/members/foo-bar/change-password
在内部,它将被处理为:

/members/.change-password.php?item=foo-bar
再说一次,这很好用,也正是我想要的

我现在需要做的是在我最初的SSL重定向逻辑中包括这一点,以确保任何更改密码的请求都被重定向到相同的URL,而不是通过https。我试过:

RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^/login(\.php)?$ [NC]
RewriteCond %{REQUEST_URI} !^/contact-us(\.php)?$ [NC]
RewriteCond %{REQUEST_URI} !^/\..*$
RewriteCond %{REQUEST_URI} !^/members/.+/change-password [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

RewriteCond %{HTTP_HOST} !^dev\.example\.com$ [NC]
RewriteCond %{SERVER_PORT} ^80$
RewriteCond %{REQUEST_URI} ^/login(\.php)?$ [NC,OR]
RewriteCond %{REQUEST_URI} ^/contact-us(\.php)?$ [NC,OR]
RewriteCond %{REQUEST_URI} ^/members/.+/change-password [NC]
RewriteRule ^(.+)\.php$ https://www.example.com/$1 [R=301,L]
但是这不起作用-我只是通过http获得页面。将
+
更改为
*
似乎会使我陷入永久重定向循环

我猜这是因为内部重写,但无论我尝试什么,我似乎都无法解决它

有人能给我建议吗

谢谢


Adam M.

对mod_rewrite文档的进一步审查让我找到了一点我遗漏的东西,具体到它在.htaccess文件中的用法。基本上,
[L]
标志实际上并没有按照规范指示最后一个。相反,您需要使用
[END]
标志(参考)

当然,这导致了另一个问题——我的主机提供商没有最新的Apache或mod_rewrite安装,因此
[END]
标志触发了ubiqitous HTTP 500内部服务器错误

那怎么办呢?我回到了我的原始规则集,知道
[L]
没有做我期望的事情,并立即发现了错误-
%{REQUEST\u URI}
值已通过内部重写进行了更新:

RewriteRule ^members/(.+)/change-password$ members/.change-password.php?url-slug=$1 [NC,QSA,L]
因此,更改原始重定向逻辑以排除此问题解决了我的问题:

RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^/login(\.php)?$ [NC]
RewriteCond %{REQUEST_URI} !^/contact-us(\.php)?$ [NC]
RewriteCond %{REQUEST_URI} !^/\..*$
RewriteCond %{REQUEST_URI} !^/members/.+/change-password$ [NC]
重写cond%{REQUEST\u URI}^/成员/\.更改密码(\.php)?[NC]

RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

RewriteCond %{HTTP_HOST} !^dev\.example\.com$ [NC]
RewriteCond %{SERVER_PORT} ^80$
RewriteCond %{REQUEST_URI} ^/login(\.php)?$ [NC,OR]
RewriteCond %{REQUEST_URI} ^/contact-us(\.php)?$ [NC,OR]
RewriteCond %{REQUEST_URI} ^/members/.+/change-password$ [NC]
RewriteRule ^(.+)(\.php)?$ https://www.example.com/$1 [R=301,L]

不要依赖自动重定向,请确保指向这些部分的链接使用
https://
。(有关详细信息,请参阅和。)@Bruno感谢您的回复,但前端的链接直接指定为https。自动重定向的原因是为那些自己键入url的人提供了安全带和大括号。虽然我可以
[F]
对url的非https请求不会提供我想要的用户体验(尽管我相信不是每个人都会同意这种方法)。只要您在开发应用程序时没有假设这些重定向存在,您的方法就确实有意义。