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

在.htaccess重定向中保留HTTP/HTTPS协议,.htaccess,mod-rewrite,rewrite,.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] 这是正确的,但是如果可能的话,我希望从%{HTTP_HOST}条件中获取协议 有没有一种方法可以让它在没有硬编码域和协议的情况下更具动态性 看起来很慢。尝

我必须在htaccess中将端口80重定向到2368,但我希望保持请求的协议完好无损,这样SSL就不会中断

我目前有:

RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC]
RewriteRule ^ http://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L]
这是正确的,但是如果可能的话,我希望从%{HTTP_HOST}条件中获取协议

有没有一种方法可以让它在没有硬编码域和协议的情况下更具动态性


看起来很慢。

尝试添加如下条件:

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTPS}:s on:(s) 
它检查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]
因此,如果禁用HTTPS,
%1
为空,协议为
http://
。如果启用了HTTPS,则“s”被分组,并且
%1
反向引用是“s”,因此协议是
HTTPS://


然而,这都是假设端口2368可以处理未加密和SSL/TLS

Jon提供的技巧是一个不错的技巧,但是如果你想使用更多的
[或]
条件,我担心它可能会失败,如果你使用更多的反向引用,你必须小心使用哪个数字(
%1
%2
或..)

我认为最优雅、稳健和干净的解决方案是设置一个变量:

# 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]
其优点还在于,初始化代码只需运行一次,因此如果您有更多的重写规则,那么生成的代码就会更短、更优雅

注意:cloudflare提供了一种常见的https设置,在这种情况下,服务器本身上的https不“打开”。在这种情况下,您需要额外的规则,如(注意顺序):

或者,您可以使用并重写它以使用一个
RewriteCond
,然后设置一个变量

看起来是这样的:

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]
或者,如果您愿意:

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]

从Apache 2.4开始,您还可以使用变量
%{REQUEST\u SCHEME}
来保留方案:

RewriteRule "^" "%{REQUEST_SCHEME}://sub.domain.com:2368%{REQUEST_URI}" [P,QSA,L]

无需以这种方式干预任何条件。

http到https重定向:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} !on
    RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
</IfModule>
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

重新启动发动机
重写cond%{HTTPS}!在…上
重写规则^(.*)$https://%{SERVER_NAME}%{REQUEST_URI}[R=301,L]
非www到www重定向:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTPS} !on
    RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
</IfModule>
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_HOST} !^www\. [NC]
    RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
</IfModule>

重新启动发动机
重写cond%{HTTP_HOST}^www\。[北卡罗来纳州]
重写规则^(.*)$https://www.%{HTTP_HOST}/$1[R=301,L]
如果您想同时使用这两个功能,那么将这两个代码块都放在上面
适当。

在我的例子中是
%{ENV:HTTPS}
,但除此之外,很棒!对于调试,您只需将
#%{HTTPS}-%%{ENV:HTTPS}-%%{ENV:proto}
附加到重定向目标,并查看它的位置。RewriteRules中设置环境变量(
^(.*)$
)的regex变量匹配和组过多,应该删除,因为之后实际上没有使用它,而不是使用破折号(-)用于简单地通过。例如,你所需要的就是重写规则[env=…]或类似内容。将proto保存在env中是一个非常好的主意。当您需要多个RewriteCond反向引用时,这很有效,但显然不起作用。只需一个小注释。这不是重定向,而是由充当代理(P标志)的服务器解决的。要执行实际重定向并要求客户端转到另一个URL,您应该使用R标志而不是P。