我有一个使用代理的 Apache 服务器,可以运行 HTTPS。它不发送 HTTPS=on 标头,而是发送 HTTP_X_FORWARDED_PROTO=https。
我想编写一个 .htaccess 规则,将所有请求从 https 重定向到 http,除非 URL 是 /user/login。
我想到的是围绕这些行(执行无限循环):
RewriteCond %{HTTP:http_x_forwarded_proto} !http
RewriteRule ^ http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
答案1
您的重定向规则的问题可能是您重复了“http_”前缀。这应该不是必要的。如果您的服务器前面有反向代理(例如 F5 或 nginx),则标头将为“X-Forwarded-Proto”,有时为“X-Forwarded_Proto”。要在重写规则中引用这些,请使用 %{HTTP:Name-Of-Header}(不区分大小写)。
为了实现在所有情况下都有效的最强大的重写,请使用如下方法:
# Make sure all SSL pages for dot-com are redirected to HTTP.
RewriteCond %{SERVER_PORT} 443 [OR]
RewriteCond %{HTTPS} on [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} https [OR]
RewriteCond %{HTTP:X-Forwarded_Proto} https
RewriteRule (.*) http://%{HTTP_HOST}/$1 [R=301,L]
有关在 RewriteCond 中使用标头的更多详细信息,请参阅Apache mod_rewrite 文档。
答案2
我认为您的初始条件的问题在于您使用的是 !http 而不是 !=http。这可能会修复无限循环。
RewriteEngine On
RewriteCond %{HTTP:http_x_forwarded_proto} !=http
RewriteCond %{REQUEST_URI} !^/user/login.*
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
这应该接受任何非 /user/login 的 https 请求并将其重写为 http。不过,我相信还有更优雅的方法可以做到这一点。例如,您可以摆脱 RewriteCond %{HTTP:http_x_forwarded_proto} !=http,它可能会同样有效,因为它应该接受传递给它的任何不包含 /user/login 的请求并将其重定向到 http。