在.htaccess重定向中保留HTTP/HTTPS协议

Vin*_*ein 30 .htaccess mod-rewrite rewrite

我必须在htaccess中将端口80重定向到2368,但我希望保持所请求的协议完整,以便SSL不会中断.

我目前有这个:

RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC]
RewriteRule ^ http://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L]
Run Code Online (Sandbox Code Playgroud)

哪个工作正常,但我希望协议从%{HTTP_HOST}条件中获取,如果可能的话.

有没有办法让这个更加动态,没有硬编码域和协议?

它似乎很慢.

TMS*_*TMS 58

由Jon提供的诀窍就是一个很好的破解,但是我怕,如果你想使用更可能突破[OR]的条件,如果你使用更多的反向引用,你必须小心使用(哪个号码%1%2或..).

我认为智能HTTP/HTTPS处理的最优雅,强大和干净的解决方案是设置变量:

# initialization code - put only once at the beginning of .htaccess
RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ - [env=proto:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ - [env=proto:http]

# simply use %{ENV:proto} in your rules:
RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC]
RewriteRule ^            %{ENV:proto}://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L]
Run Code Online (Sandbox Code Playgroud)

优点还在于初始化代码只需要运行一次,因此如果你有更多的重写规则,那么结果代码会更短更优雅.

请注意,常见设置是使用cloudflare提供的https,在这种情况下,HTTPS不会在服务器本身上"打开".在这种情况下,您需要额外的规则,如(注释顺序):

RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"' [OR]
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ - [env=proto:http]
RewriteCond %{HTTP:CF-Visitor} '"scheme":"https"' [OR]
RewriteCond %{HTTPS} =on
RewriteRule ^(.*)$ - [env=proto:https]
Run Code Online (Sandbox Code Playgroud)

  • 就我而言,它是`%{ENV:HTTPS}`,但除此之外,太好了!对于调试,您只需在重定向目标后面附加`#%{HTTPS}-%{ENV:HTTPS}-%{ENV:proto}`并查看它的去向。 (2认同)
  • RewriteRules 中设置环境变量 (`^(.*)$`) 的正则表达式变量 match 和 group 过多,应该删除,因为之后实际上并没有使用它,而是使用破折号 (-) 简单地传递通过。例如,您所需要的只是“RewriteRule”。- [env=...]` 或类似的。 (2认同)

Ger*_*der 47

从Apache 2.4开始,您还可以使用该变量%{REQUEST_SCHEME}来保留方案:

RewriteRule "^" "%{REQUEST_SCHEME}://sub.domain.com:2368%{REQUEST_URI}" [P,QSA,L]
Run Code Online (Sandbox Code Playgroud)

无需以这种方式干涉任何条件.


Jon*_*Lin 22

尝试添加如下条件:

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTPS}:s on:(s) 
Run Code Online (Sandbox Code Playgroud)

哪个检查HTTPS已关闭或已启用,您可以使用反向引用来获取"s"字符:

RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC]
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTPS}:s on:(s) 
RewriteRule ^ http%1://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L]
Run Code Online (Sandbox Code Playgroud)

因此,如果HTTPS关闭,%1则为空,协议为http://.如果启用HTTPS,则"s"被分组,%1反向引用为"s",因此协议为https://.

然而,这一切假设端口2368可以处理这两种加密和SSL/TLS.

  • 只是一个小小的评论。这不是重定向,这是由充当代理的服务器(P 标志)解决的。要进行实际重定向并要求客户端转到另一个 URL,您应该使用 R 标志而不是 P。 (2认同)

Mag*_*son 7

或者,您可以使用由Jon Lin作为答案发布的解决方案,并将其重写为使用一个RewriteCond,然后按照TMS的答案中的建议设置变量.

这看起来像这样:

RewriteCond %{HTTPS}s ^(on(s)|offs)$
RewriteRule ^ - [env=s:%2]

RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC]
RewriteRule ^ http%{ENV:s}://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L]
Run Code Online (Sandbox Code Playgroud)

或者,如果您愿意:

RewriteCond %{HTTPS}s ^(on(s)|offs)$
RewriteRule ^ - [env=proto:http%2]

RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC]
RewriteRule ^ %{ENV:proto}://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L]
Run Code Online (Sandbox Code Playgroud)