我使用Network Solutions作为托管服务提供商,提供UNIX托管包。我需要将某些页面重定向到https(登录等)。经过大量测试后,我最终得到了以下.htaccess条目:
RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://[domain_redacted]/$1 [R=301,L]
这导致了无限重定向循环。在与Network Solutions讨论后,他们告诉我需要301重定向(显然我正在做的不是301重定向......),所以我在.htaccess中尝试了以下内容:
Redirect 301 / https://[domain_redacted]/
当然,这会导致无限循环,正如人们所期望的那样。由于这些方法都不起作用,我在我的服务器上放了以下PHP脚本来通过PHP测试https检测:
<?php
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') {
echo 'HTTPS IS ON';
} else {
echo 'HTTPS IS OFF';
}
?>
通过HTTP和HTTPS请求此页面时,脚本将返回OFF。
那么,在Apache或PHP中检测HTTPS服务器端还有哪些其他方法?
答案 0 :(得分:3)
我只是这样问我可以回答这个问题,主要是因为我无法在任何地方找到解决方案。
背景: Network Solutions处理共享主机系统的方式,实际上并不连接到服务器,而是连接到代理服务器(这很有意义)。执行https重定向时,例如:
RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$ [OR]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://[domain_redacted]/$1 [R=301,L]
事实上,您确实将页面重定向到HTTPS。但是,您正在使用代理服务器而不是托管服务器执行HTTPS事务。代理服务器通过端口80将您的HTTPS连接转换为HTTP。当尝试使用.htaccess检测到此情况时,服务器看不到HTTPS,因为托管服务器和代理之间的连接始终是端口80上的HTTP。 PHP从Apache中提取HTTPS变量,它将通过.htaccess检测HTTP具有相同的结果。
因此,除非我弄错了,否则在使用Network Solutions的共享主机时,无法执行自引用HTTP到HTTPS重定向。请求必须以某种方式更改(通过更改URI或查询字符串),以便服务器检测更改。当然,这是完全可欺骗的(例如,无论你如何更改URI /查询字符串,只需将其作为http键入浏览器,服务器永远不会知道),否定HTTPS的全部要点。
我尝试检查%{HTTP_REFERER}是否引用了自己,但它没有使用mod_rewrite。
我能想到的唯一解决方法是通过javascript进行客户端检测。这有其自身的缺陷(NoScript等)。但我无法想出另一个问题的解决方案。以下代码将近似301重定向。
if(document.URL.match(/^https/i) == null) {
var NetworkSolutionsSucks = document.createElement('meta');
with (NetworkSolutionsSucks) {
httpEquiv = 'refresh';
content = '0;url=' + document.URL.replace(/^http/i,'https');
}
document.head.appendChild(NetworkSolutionsSucks);
var msg = document.createElement('div');
with (msg) {
innerHTML = 'This page requires a secure connection, you are being redirected.<br><br>';
innerHTML += 'If the page does not load, please click <a href="' + document.URL.replace(/^http/i,'https') + '">Here</a>';
}
var newBody = document.createElement('body');
newBody.appendChild(msg);
document.replaceChild(newBody, document.body);
}
将上述脚本包含在您要强制HTTPS的任何文档的标题中(强制HTTP留作读者练习 - 这是一个更简单的脚本,不需要手动重定向某些失败)。你应该使用一个noscript标签(显然);您可以使用以下内容:
<noscript id="networkSolutionsHTTPSRedirect">This site requires javascript in order to operate properly. Please enable javascript and refresh this page.</noscript>
<style type="text/css">#networkSolutionsHTTPSRedirect{position: fixed; height: 100%; width: 100%; top: 0; left: 0; z-index: 500;}</style>
<script type="text/javascript">
<!--
document.getElementById("networkSolutionsHTTPSRedirect").style.visibility = "hidden";
document.getElementById("networkSolutionsHTTPSRedirect").style.display = "none";
-->
</script>
如果您在每个页面上执行以下操作,则可以尝试强制整个站点使用HTTPS:
<?php
if((!isset($_ENV['HTTP_REFERER']) || preg_match('/^http[s]{0,1}:\/\/' . $_ENV['SERVER_NAME'] . '/i',$_ENV['HTTP_REFERER']) == 0) && !isset($_ENV[HTTP_X_HTTPS_REDIRECT])) {
header('X-HTTPS-REDIRECT: true\n');
header('Location:' . preg_replace('/^http/','https', $_ENV['SCRIPT_URI']));
}
?>
这应该为所有没有为您的站点设置HTTP_REFERER的请求引入重定向,并且不带有您注入的自定义X-HTTPS-REDIRECT标头。这并不能真正检测到HTTPS,而是执行合理的传真(至少在服务器端)。
当然,您可以修改正则表达式,以便只有某些网站需要通过将REFERER与您想要保护的域部分相匹配才能成为HTTPS,然后取消测试以强制使用HTTP。
答案 1 :(得分:2)
我也有网络解决方案作为我的提供商。最后一次使用PHP编写脚本也没有用,导致无限循环。
网络解决方案提供以下代码作为Javascript中从http://到https://的最佳重定向,说没有办法在服务器端执行此操作。
<script language="javascript">
if (document.location.protocol != "https:")
{
document.location.href = "https://subdomain.yourdomain.com" + document.location.pathname;
};
</script>
可在此处找到有关该主题的信息。 http://www.networksolutions.com/support/ssl-redirects/
答案 2 :(得分:0)
使用以下命令仅强制某些页面为https。在您强制http的部分中,只需包含以否定格式强制使用https的部分/页面。
这样的事情,也许是:(。htaccess)
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
# Force https for mode= login, account or register, and the /admin directory:
RewriteCond %{HTTPS} !=on
RewriteCond %{QUERY_STRING} mode=(login|account|register) [OR]
RewriteCond %{REQUEST_URI} admin/
RewriteRule (.+) https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
# force http for all NON login, account, register (query string)
# and anything else outside the /admin directory
RewriteCond %{HTTPS} on
RewriteCond %{QUERY_STRING} !mode=(login|account|register)
RewriteCond %{REQUEST_URI} !admin/
RewriteRule (.+) http://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
答案 3 :(得分:0)
PHP变量:
$_ENV['SCRIPT_URI']
将返回完整的请求字符串,包括协议。
<?php
if(preg_match('/^https/i',$_ENV['SCRIPT_URI']) == 0) {
header('Location: ' . preg_replace('/^http/i','https', $_ENV['SCRIPT_URI']));
}
?>
答案 4 :(得分:0)
这是使用 Networksolutions 重定向的唯一干净方式。花了我几个小时的测试。最适合 SEO。 Network Solutions 是一个具有挑战性的托管平台。
这将起作用 .htaccess 您只需将 changeexample.com 替换为您的域即可。很简单。
## Base Redirects ##
# Turn on Rewrite Engine
RewriteEngine On
# Remove trailing slash from non-filepath urls
RewriteCond %{REQUEST_URI} /(.+)/$
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ https://changeexample.com/%1 [R=301,L]
# Include trailing slash on directory
RewriteCond %{REQUEST_URI} !(.+)/$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+)$ https://changeexample.com/$1/ [R=301,L]
# Force HTTPS and remove WWW
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [OR,NC]
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://changeexample.com/$1 [R=301,L]
祝你好运!这是截至 2021 年 5 月 14 日的最新数据