33

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

我目前有这个:

RewriteCond %{HTTP_HOST} ^sub.domain.com$ [NC]
RewriteRule ^ http://sub.domain.com:2368%{REQUEST_URI} [P,QSA,L]

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

有没有办法在没有硬编码域和协议的情况下让它变得更加动态?

它看起来很慢。

4

5 回答 5

65

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]

优点还在于初始化代码只需要运行一次,所以如果你有更多的重写规则,那么生成的代码会更短更优雅。

请注意,常见的设置是 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]
于 2013-12-06T08:59:19.083 回答
51

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

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

不用这样插手任何条件。

于 2016-11-22T10:03:18.223 回答
26

尝试添加如下条件:

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。

于 2013-10-15T03:07:01.897 回答
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]

或者,如果您愿意:

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]
于 2015-08-28T13:03:02.683 回答
-1

http到https重定向:

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

非 www 到 www 重定向:

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

如果您想同时使用这两种功能,请适当地放置上述两个代码块。

于 2018-10-26T10:42:07.553 回答