#1 楼
对于Apache,您可以使用mod_ssl
通过SSLRequireSSL Directive
强制使用SSL:该指令禁止访问,除非为当前连接启用了SSL上的HTTP(即HTTPS)。这在启用SSL的虚拟主机或目录中非常方便,可防止配置错误暴露应受保护的内容。当存在此伪指令时,将拒绝所有未使用SSL的请求。
这不会重定向到https。要重定向,请尝试在您的.htaccess文件中使用
mod_rewrite
进行以下操作RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
或
http://www.askapache.com/htaccess/http-https-rewriterule-redirect.html
如果您的提供者禁用了.htaccess,那么您也可以在PHP中解决此问题(自您要了,但是无论如何)
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
if(!headers_sent()) {
header("Status: 301 Moved Permanently");
header(sprintf(
'Location: https://%s%s',
$_SERVER['HTTP_HOST'],
$_SERVER['REQUEST_URI']
));
exit();
}
}
#2 楼
我找到了适用于代理服务器和非代理服务器的mod_rewrite
解决方案。如果您正在使用CloudFlare,AWS Elastic Load Balancing,Heroku,OpenShift或任何其他Cloud / PaaS解决方案,并且遇到重定向循环使用正常的HTTPS重定向,请尝试以下代码段。
RewriteEngine On
# If we receive a forwarded http request from a proxy...
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
# ...or just a plain old http request directly from the client
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
# Redirect to https version
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
评论
这太棒了!但是也许需要添加发布条件? RewriteCond%{REQUEST_METHOD}!^ POST $
– Aleksej
17年9月16日在9:40
@Aleksej是的,这破坏了未加密的POST请求。但是我认为这是一件好事。这样,人们会注意到他们在做错事。我想最好的办法是将它们重定向到一个页面,该页面告知他们如何正确使用您的服务。
–raphinesse
18 Mar 20 '18在11:53
@raphinesse你知道这个问题的答案:stackoverflow.com/questions/51951082/…
– RNN
18年8月21日在14:37
#3 楼
PHP解决方案直接从Gordon的非常全面的答案中借用,我注意到您的问题提到在强制HTTPS / SSL连接时特定于页面。
function forceHTTPS(){
$httpsURL = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
if( count( $_POST )>0 )
die( 'Page should be accessed with HTTPS, but a POST Submission has been sent here. Adjust the form to point to '.$httpsURL );
if( !isset( $_SERVER['HTTPS'] ) || $_SERVER['HTTPS']!=='on' ){
if( !headers_sent() ){
header( "Status: 301 Moved Permanently" );
header( "Location: $httpsURL" );
exit();
}else{
die( '<script type="javascript">document.location.href="'.$httpsURL.'";</script>' );
}
}
}
然后,在要通过PHP强制连接的这些页面的顶部附近,可以
require()
包含此(和任何其他)自定义函数的集中文件,然后只需运行forceHTTPS()
函数。HTACCESS / mod_rewrite解决方案
我还没有亲自实现这种解决方案(为简单起见,我倾向于使用PHP解决方案,就像上面的解决方案一样),但是以下可能是,至少是一个好的开始。
RewriteEngine on
# Check for POST Submission
RewriteCond %{REQUEST_METHOD} !^POST$
# Forcing HTTPS
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{SERVER_PORT} 80
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_secure [OR]
RewriteCond %{REQUEST_URI} ^something_else_secure
RewriteRule .* https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
# Forcing HTTP
RewriteCond %{HTTPS} =on [OR]
RewriteCond %{SERVER_PORT} 443
# Pages to Apply
RewriteCond %{REQUEST_URI} ^something_public [OR]
RewriteCond %{REQUEST_URI} ^something_else_public
RewriteRule .* http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
评论
出于好奇,为什么要使用RewriteCond%{REQUEST_METHOD}!^ POST $?
– depoulo
13年6月29日在6:43
因为POST参数未保留在重定向中。如果要确保所有POST提交都是安全的,则可以省略该行(任何不安全的POST提交都将被忽略)。
–路易斯·史蒂文森(Luke Stevenson)
13年6月30日在6:35
@Lucanos-如何编写一个POST时不强制重定向到http或https的RewriteCond?我的.htaccess会在某些特定页面上强制使用HTTPS,然后在其余页面上强制使用HTTP。但是,在HTTPS页面上,有一些表单可以提交到我的Web根目录。该表格将操作网址指定为HTTPS。但是,由于Web根目录不是指定用于强制HTTPS的页面之一,因此我的.htaccess会强制进行重定向-这意味着POST变量会丢失。如何防止POST上的重定向?
– StackOverflowNewbie
2014年7月8日在19:23
@StackOverflowNewbie:RewriteCond%{REQUEST_METHOD}!^ POST $这一行应该防止POST提交受到这些重定向的影响。
–路易斯·史蒂文森(Luke Stevenson)
2014年7月9日在6:15
我喜欢这个PHP版本。考虑到POST会更好,并且如果已经发送了标头,则处理会更好。
– TheStoryCoder
16-2-29在10:38
#4 楼
基于Mod重写的解决方案:在htaccess中使用以下代码会自动将所有http请求转发到https。
RewriteEngine on
RewriteCond %{HTTPS}::%{HTTP_HOST} ^off::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
这将重定向您的非-www和www http请求https的www版本。
另一种解决方案(Apache 2.4 *)
RewriteEngine on
RewriteCond %{REQUEST_SCHEME}::%{HTTP_HOST} ^http::(?:www\.)?(.+)$
RewriteRule ^ https://www.%1%{REQUEST_URI} [NE,L,R]
这不适用于自2.4起,将较低版本的apache版本作为%{REQUEST_SCHEME}变量添加到mod-rewrite中。
#5 楼
我只想指出,在跨目录深度使用多个.htaccess文件时,Apache具有最差的继承规则。两个主要陷阱:默认情况下,仅执行最深.htaccess文件中包含的规则。您必须指定RewriteOptions InheritDownBefore
指令(或类似指令)才能更改此设置。 (请参阅问题)该模式应用于相对于子目录的文件路径,而不应用于包含具有给定规则的.htaccess文件的上层目录。 (请参阅讨论)。这意味着如果您在子目录中使用任何其他.htaccess文件,则Apache Wiki上建议的全局解决方案将不起作用。我写了一个修改后的版本,可以做到:
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteOptions InheritDownBefore
# This prevents the rule from being overrided by .htaccess files in subdirectories.
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [QSA,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/
#6 楼
简单易用,只需添加以下内容RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
评论
这几乎是整个互联网上的人们告诉您的强制使用https的行为。但是,每次这样做,我的整个网站都会被禁止或您无权查看。诸如此类...我在做什么错?我只想知道您是否有任何想法,然后再对此发表问题。
– ThN
18/12/14在13:53
我有一个类似的问题,我不得不将规则应用于https.conf文件。请参阅下面的答案。
–Risteard
19年7月2日在10:19
#7 楼
该代码对我有用RewriteEngine On
RewriteBase /
RewriteCond %{HTTP:X-HTTPS} !1
RewriteRule ^(.*)$ https://%{HTTP_HOST}/ [R=301,L]
#8 楼
简单的一个:RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.example\.com)(:80)? [NC]
RewriteRule ^(.*) https://example.com/ [R=301,L]
order deny,allow
用example.com替换您的网址
评论
没有!网站网址必须是动态的。
–阿米尔·萨凡德(Amir Savand)
18年8月23日在12:08
#9 楼
尝试使用此代码,它将适用于所有版本的URL,例如website.com
www.website.com
http://website.com
http://www.website.com
RewriteCond %{HTTPS} off
RewriteCond %{HTTPS_HOST} !^www.website.com$ [NC]
RewriteRule ^(.*)$ https://www.website.com/ [L,R=301]
评论
在我们的情况下,这非常好,因为我们目前混合使用HTTP和https流量。对于我们的管理区域,我们只是弹出.htaccess脚本,同时保留网站的其余部分http。
–迈克尔·J·卡尔金斯(Michael J. Calkins)
2014-09-24 23:11
当我使用mod_rewrite方法时,会发送到https,但出现“页面无法正确重定向”错误。
–捷克文
2014年10月9日12:00
后续:如果遇到类似的问题,请检查服务器和HTTP变量。如果服务器使用代理,则可能要使用%{HTTP:X-Forwarded-Proto}或%{HTTP:X-Real-Port}变量来检查SSL是否已打开。
–捷克文
2014年10月9日,12:47
如果您在代理后面运行的服务器(CloudFlare,Openshift)上遇到重定向循环,请参阅此答案以获取适用于这种情况的解决方案。
–raphinesse
2015年12月3日,11:58
@GTodorov-删除空间为我破坏了重写器。以我对重写器的有限了解,语法为RewriteRule
– Sphinxxx
16年6月30日在13:37