htaccess重定向到https:// www

big*_*ben 301 apache .htaccess mod-rewrite https redirect

我有以下htaccess代码:

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteCond !{HTTPS} off
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

</IfModule>
Run Code Online (Sandbox Code Playgroud)

我希望我的网站可以重定向到https://www.HTTPS,并强制执行www.子域,但是当我访问http://www.(没有HTTPS)时,它不会将我重定向到https://wwwHTTPS.

Mic*_*ski 613

要首先强制使用HTTPS,您必须检查正确的环境变量%{HTTPS} off,但是上面的规则会预先设置www.由于您要执行第二条规则www.,请不要在第一条规则中使用它.

RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Run Code Online (Sandbox Code Playgroud)

关于代理

当某些形式的代理背后,客户端通过HTTPS连接到代理,负载均衡器,乘客应用程序等时,该%{HTTPS}变量可能永远不会on导致重写循环.这是因为即使客户端和代理/负载均衡器使用HTTPS,您的应用程序实际上也会接收纯HTTP流量.在这些情况下,请检查X-Forwarded-Proto标头而不是%{HTTPS}变量.这个答案显示了适当的过程

  • 当我使用``RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R = 301]``一个像http://exaple.com/?bla=%20这样的网址变成了http://exaple.com/?bla=%2520,即已对百分号进行编码.考虑使用标志"NE``来防止双重编码:``RewriteRule.*https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R = 301]`` (18认同)
  • 在某些情况下,您的证书可能只适用于单个域(它可能适用于www,但是,例如,不是没有).在这种情况下,首先重定向到正确的域,然后重定向到https,否则您将在浏览器中收到证书错误消息. (13认同)
  • 这给了我一个服务器上的重定向循环,其他工作.我真的不知道为什么 (5认同)
  • @ user151496失败的服务器是否使用任何类型的HTTP代理,例如通过Varnish缓存或Passenger?如果是这样,您可能必须检查`X-Forwarded-Proto`标头以验证HTTPS而不是'%{HTTPS}`变量.你没有说哪个部分导致循环,`www`或HTTPS部分,但这是我想到的第一件事. (4认同)
  • 一旦我将`RewriteEngine On`添加到.htaccess文件的开头,这就有效了 (4认同)
  • 严格来说,上面的两个规则是错误的顺序.如果有一个请求来自`http:// example.com`(即HTTP和非www),那么你将获得双重定向.首先是"https:// example.com"(第一条规则),然后是"https:// www.example.com"(第二条规则).您可以通过简单地颠倒这两个规则来解决这个问题,因为无论如何这两个规则都会重定向到HTTPS. (4认同)
  • "不要把www.放在这里" - 为什么不呢?在第一个`RewriteRule`中包含`www`将避免第二次重定向(如果需要) - 尽管您可能需要对所需主机进行硬编码.`^(.*)$`可以简化为`.*`. (2认同)
  • @KayakinKoder当在这个上下文中使用`[R]`时,会自动/隐式地添加`[QSA]`,并且在重写的URL中不存在`?`,所以这里它是多余的. (2认同)
  • @Toto``NC`标志应该从`RewriteCond%{HTTP_HOST}!^ www\.`指令中省略.请注意,这是一个_negated_模式.如果你在这里包含`NC`标志,那么它不会重定向一个格式错误的请求,如`WwW.example.com`(来​​自"一些机器人和脚本调用") - 它与你想要实现的相反.当它不是`www.(全小写)时,你希望它重定向. (2认同)

Lar*_*zan 146

Michals的回答对我有用,虽然有一个小修改:

问题:

当您拥有单个站点安全证书时,尝试访问您的页面的浏览器不使用https:// www.(或者您的证书所涵盖的任何域)将显示丑陋的红色警告屏幕,甚至它接收重定向到安全且正确的https页面之前.

首先使用重定向到www(或证书涵盖的任何域),然后才进行https重定向.这将确保您的用户不会遇到任何错误,因为您的浏览器会看到不包含当前网址的证书.

#First rewrite any request to the wrong domain to use the correct one (here www.)
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

#Now, rewrite to HTTPS:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Run Code Online (Sandbox Code Playgroud)

  • +1,因为它是这种情况下更好的选择,但请注意,如果客户端访问"https:// example.com",这不会阻止同样的问题发生,但在我看来,这是最不可能的格式由用户输入.(接受的答案也会有同样的问题) (5认同)

And*_*rew 95

如果您使用的是CloudFlare或类似的CDN,则会在此处提供%{HTTPS}解决方案时出现无限循环错误.如果您是CloudFlare用户,则需要使用以下内容:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Run Code Online (Sandbox Code Playgroud)

  • 我为我们的环境修改了`= http`到`!= https`.如果没有声明`X-Forwarded-Proto`标题,那么`!= https`就可以了. (3认同)
  • 请注意,Cloudflare支持网站上的当前建议略有不同:https://support.cloudflare.com/hc/en-us/articles/200170536-How-do-I-redirect-HTTPS-traffic-with-Flexible- SSL-和Apache- (2认同)

Ami*_*ati 55

糟糕的解决方案和为什么!

不要使用上面的解决方案,因为当您使用的代码类似于:

RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.example.com%{REQUEST_URI} [L,R=301]
Run Code Online (Sandbox Code Playgroud)

浏览器转到:

http://example.com
Run Code Online (Sandbox Code Playgroud)

然后重定向到:

https://example.com
Run Code Online (Sandbox Code Playgroud)

然后重定向到:

https://www.example.com
Run Code Online (Sandbox Code Playgroud)

这对服务器的请求太多了


最佳解决方案和答案

此代码有一个[OR]条件,以防止URL上的双重更改!

RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com%{REQUEST_URI} [R=301,L]
Run Code Online (Sandbox Code Playgroud)

大多数答案甚至接受了一个,不要使用这个技巧.

  • 如果你想保留domainname变量,你可以使用它:`RewriteEngine On RewriteCond%{HTTPS} off RewriteCond%{HTTP_HOST}!^ www \.[NC] RewriteRule.*https://www.% {HTTP_HOST}%{REQUEST_URI} [L,R = 301] RewriteCond%{HTTPS} off RewriteRule.*https://%{HTTP_HOST}%{REQUEST_URI} [L ,R = 301]` (4认同)
  • 是的,给出的代码导致2个重定向 - 我不是在争论 - 我只是说你只需要反转这些规则来解决这个问题,不需要进行其他更改.("接受"的答案确实是错误的 - 这似乎是你所指的 - 指令的顺序错误.) (3认同)
  • “错误的解决方案,为什么!” -这些规则的顺序错误。颠倒这两个规则,这将是正确的-您只会获得一个重定向,而不是两个。 (2认同)

lli*_*oor 33

这是我找到Proxy而不是代理用户的最佳方式

RewriteEngine On

### START WWW & HTTPS

# ensure www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

### END WWW & HTTPS
Run Code Online (Sandbox Code Playgroud)

  • 正确**这是我为代理而不是代理用户找到的最佳方式** +1 (2认同)
  • 有史以来最好的解决方案。 (2认同)

小智 27

那里有很多解决方案.这是apache wiki的链接,它直接处理这个问题.

http://wiki.apache.org/httpd/RewriteHTTPToHTTPS

RewriteEngine On
# This will enable the Rewrite capabilities

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS

RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e.  http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context
Run Code Online (Sandbox Code Playgroud)

  • 这不会将URL重写为https:// www.但它重写为https:// (6认同)

sta*_*een 11

要将http://https://重定向到https:// www,您可以在所有版本的apache上使用以下规则:

RewriteEngine on

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]
Run Code Online (Sandbox Code Playgroud)

Apache 2.4

RewriteEngine on

RewriteCond %{REQUEST_SCHEME} http [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]
Run Code Online (Sandbox Code Playgroud)

请注意,自apache 2.4起,%{REQUEST_SCHEME}变量可供使用.


Ahm*_*ais 8

如果您使用的是CloudFlare,请确保使用类似的内容.

# BEGIN SSL Redirect
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# END SSL Redirect
Run Code Online (Sandbox Code Playgroud)

这将使您免于重定向循环,并将您的站点安全地重定向到SSL.

PS如果检查mod_rewrite.c是个好主意!