检测HTTP或HTTPS,然后在JavaScript中强制HTTPS


297

有什么方法可以检测HTTP或HTTPS,然后通过JavaScript强制使用HTTPS?

我有一些用于检测HTTP或HTTPS的代码,但是我不能强迫它使用https:

我正在使用window.location.protocol属性设置站点的任何内容,https:然后刷新页面以希望将新的httpsed URL重新加载到浏览器中。

if (window.location.protocol != "https:") {
   window.location.protocol = "https:";
   window.location.reload();
}

15
这是在服务器端更加可靠(高效)地处理的。
昆汀

3
我想你是对的。作为使用MITM攻击的攻击者,我可以删除此代码。因此,它仅提供针对被动攻击的防护。
ndevln 2014年


1
@NeoDevlin http上的MITM攻击者也可以替换服务器端重定向
Alex Lehmann

1
究竟。在2018年,没有任何理由不使用HSTS。这是强制HTTPS的唯一安全方法。

Answers:


499

尝试这个

if (location.protocol !== 'https:') {
    location.replace(`https:${location.href.substring(location.protocol.length)}`);
}

location.href = blah将此重定向添加到浏览器历史记录。如果用户单击“后退”按钮,他们将被重定向回同一页面。最好使用location.replace它,因为它不会将此重定向添加到浏览器历史记录中。


3
为什么windowdocument呢?
webjay 2013年


11
字符串比较应该是!==吗?
Wes Turner

5
@WesTurner没关系。它们都总是字符串。如果一个是数字或布尔值,则可能会有所不同。
Soumya

15
location.replace(url)location.href = url这种情况要好得多。您不希望这种重定向出现在浏览器的历史记录中,也不希望用户单击后退按钮只是为了再次重定向。
弗朗西斯科·萨拉博佐(Frank Francisco Zarabozo)'18年

58

设置location.protocol导航到新URL。无需解析/切片任何内容。

if (location.protocol !== "https:") {
  location.protocol = "https:";
}

Firefox 49有一个可以正常工作的错误httpshttps:不起作用。据说是在Firefox 54中修复的


2
if window.location.href.match('http:') window.location.href = window.location.href.replace('http', 'https')适用于最新的FF和Chrome。
马丁·斯坦纳德

2
location.protocol = "https";似乎在Firefox 28中工作了
Nick Russler 2014年

1
废话打破后退按钮。使用location.replace代替。
好战的黑猩猩

22

这不是一个好主意,因为您只是将用户临时重定向到https,而浏览器不会保存此重定向。

您描述Web服务器(apache,nginx等)的任务http 301,http 302


3
同意。在服务器上强制使用https更可靠
–HoàngLong

3
如果保留哈希值很重要,我可以看到它正在使用。它不会发送到服务器,某些浏览器不会保留它。
杰森·赖斯

下面是设置Azure的网站的链接仅HTTPS ... blogs.msdn.com/b/benjaminperkins/archive/2014/01/07/...
OzBob

1
不一定正确。有一种观点认为301是出于缓存原因的恶魔。getluky.net/2010/12/14/301-redirects-can-be-on-on
Fivedogit

2
虽然这样做在客户端通常不是一个好主意,但这并不是所要的。而且您没有显示如何执行此操作,因此这不是答案。同样,在如今的静态网页中,通常没有办法在服务器端执行此操作(请考虑使用Github页面),这意味着您必须在客户端上执行此操作。不过,您可以通过添加规范的链接标签来避免人们点击非SSL版本来改善搜索效果。
oligofren

16

这个怎么样?

if (window.location.protocol !== 'https:') {
    window.location = 'https://' + window.location.hostname + window.location.pathname + window.location.hash;
}

不过,理想情况下,您应该在服务器端执行此操作。


它缺少端口
eadmaster

13
if (location.protocol == 'http:')
  location.href = location.href.replace(/^http:/, 'https:')

5

不是使用Java脚本来回答这个问题的方法,但是如果您使用CloudFlare,则可以编写页面规则来将用户更快地重定向到HTTPS,而且它是免费的。在CloudFlare的页面规则中看起来像这样:

在此处输入图片说明


实际上,我发现这非常有用,不是为了回答框架中的问题,而是为不提供始终在线SSL的SaaS服务提供有关可能更可靠的方式的有用信息。
MrMesees'Apr 11'16

3

你可以做:

  <script type="text/javascript">        
        if (window.location.protocol != "https:") {
           window.location.protocol = "https";
        }
    </script>

有用。这是重定向的标准方法吗?可以在所有浏览器中使用吗?
mahfuz



0

我喜欢这个问题的答案。但是要想发挥创造力,我想再分享一种方式:

<script>if (document.URL.substring(0,5) == "http:") {
            window.location.replace('https:' + document.URL.substring(5));
        }
</script>

-1
<script type="text/javascript">
        function showProtocall() {

            if (window.location.protocol != "https") {
                window.location = "https://" + window.location.href.substring(window.location.protocol.length, window.location.href.length);
                window.location.reload();
            }
        }
        showProtocall();
</script>

-1

嗨,我使用此解决方案效果很好。无需检查,只需使用https。

<script language="javascript" type="text/javascript">
document.location="https:" + window.location.href.substring(window.location.protocol.length, window.location.href.length);
</script>

3
即使协议为https,这也不会刷新页面吗?
安东尼

-2

我刚刚通过Pui Cdm测试了所有脚本变体,包括上面的答案以及使用php,htaccess,服务器配置和Javascript的许多其他答案,结果是该脚本

<script type="text/javascript">        
function showProtocall() {
        if (window.location.protocol != "https") {
            window.location = "https://" + window.location.href.substring(window.location.protocol.length, window.location.href.length);
            window.location.reload();
        }
    }
    showProtocall();
</script> 

vivek-srivastava提供的 效果最佳,并且您可以在Java脚本中添加进一步的安全性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.