Detect HTTP or HTTPS then force HTTPS in JavaScript
Asked Answered
E

13

366

Is there any way to detect HTTP or HTTPS and then force usage of HTTPS with JavaScript?

I have some codes for detecting the HTTP or HTTPS but I can't force it to use https: .

I'm using the window.location.protocol property to set whatever the site is to https: then refresh the page to hopefully reload a new https'ed URL loaded into the browser.

if (window.location.protocol != "https:") {
   window.location.protocol = "https:";
   window.location.reload();
}
Enrika answered 18/1, 2011 at 10:52 Comment(5)
This is far more reliably (and efficiently) handled server side.Typhon
I think you are right. As an attacker using a MITM attack, I could just delete this code. So it offers only protection against passiv attacks.Hanshaw
The detection part is a duplicate of How can I use JavaScript on the client side to detect if the page was encrypted? from 2008.Fleuron
@NeoDevlin a MITM attacker on http can replace a server side redirect as wellExcide
Exactly. In 2018, there is no excuse not to use HSTS. This is the only safe way to force HTTPS.Acidimetry
E
607

Try this

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

location.href = blah adds this redirect to the browser history. If the user hits the back button, they will be redirected back to the the same page. It is better to use location.replace as it doesn't add this redirect to the browser history.

Erickson answered 18/1, 2011 at 11:2 Comment(15)
Why window and not document?Dross
@Dross see https://mcmap.net/q/36258/-what-39-s-the-difference-between-window-location-and-document-location and https://mcmap.net/q/36258/-what-39-s-the-difference-between-window-location-and-document-locationErickson
Should the string comparison be !==?Oldfangled
@WesTurner It shouldn't matter either way. They're both always going to be strings. If one was a number or a boolean, then it might make a difference.Erickson
What about using location,protocol? Now a days everyone suggesting it.Bittern
instead of doing substring you can just use window.location.hostnameSchoening
I like to use: if (window.location.protocol == "http") window.location.href = "https" + window.location.href.slice(4);Colcannon
While this does work, it causes a page refresh upon entering the website for the first time. Not an elegant solution.Hurlburt
@Colcannon you missed a colon. This works: if (window.location.protocol === 'http:') { window.location.href = 'https:' + window.location.href.slice(5); }Tenacious
@Zero3: I haven't tested myself, but I would expect that since he left out the colon in both cases, it would come out to the same thing. After all, he left out the domain name, but that makes no difference because it is the same thing for both protocols.Hypocotyl
@Hypocotyl I'm afraid that is not how string equality works. It checks whether both strings are completely identical. So when window.location.protocol is http:, it will not be equal to http, and thus the code does not work as intended. According to MDN, then window.location.protocol includes the colon after the protocol name. Also note that the domain name is not stored in window.location.protocol at all, so it is not used in the comparison in any way.Tenacious
location.replace(url) would be much better than location.href = url for this case. You don't want this redirection in the browser's history or the user hitting the back button just to get redirected again.Mcalpine
Should this answer not be using window.location. instead of directly location. It's both clearer syntactically and safer incase location is locally overridden. See #4709537Rubie
It should be noted that future protocols may exist just like https did not exist at one point and is now standard. So checking that its not https and forcing to https is different than checking that its http and forcing to https (which is what the question asked too). Suppose some protocol exists in 2026 like httpz and is even more standard, and server rules auto route users to that, now we will be forcing them back to the older https protocol, unless we update our JS everywhere. Better to just check protocol = http then redirect to https. Safer for futureRoveover
Works great in instances where the .htaccess or apache vhost methods for doing this are creating issues.Superstitious
B
79

Setting location.protocol navigates to a new URL. No need to parse/slice anything.

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

Firefox 49 has a bug where https works but https: does not. Said to be fixed in Firefox 54.

Bulla answered 5/4, 2012 at 21:8 Comment(3)
if window.location.href.match('http:') window.location.href = window.location.href.replace('http', 'https') works on latest FF and Chrome.Shifra
location.protocol = "https"; seems to work though in firefox 28Tracheostomy
Crap that breaks the back button. Use location.replace instead.Infallible
T
26

It is not good idea because you just temporary redirect user to https and browser doesn't save this redirect.

You describe task for web-server (apache, nginx etc) http 301, http 302

Transformer answered 7/7, 2012 at 12:20 Comment(5)
agree. Forcing https on server is far more reliableLangley
I could see it being used if preserving the hash value is important. It is not sent to the server and some browsers do not preserve it.Venery
Here's a link to Set Azure Web Site for https only ... blogs.msdn.com/b/benjaminperkins/archive/2014/01/07/…Crossgrained
Not necessarily true. There is a school of thought that 301 is the devil for caching reasons. getluky.net/2010/12/14/301-redirects-cannot-be-undonOballa
While it's true that it's generally not a good idea to do this client side, this is not what was asked. And you do not show how to do it, hence this is not an answer. Also, in these days of static webpages, often there is no way to do this server side (think Github pages), meaning you have to do this on the client. Still, you can help improve the search by adding canonical link tags to avoid people hitting the non-ssl version.Confiscatory
S
17
if (location.protocol == 'http:')
  location.href = location.href.replace(/^http:/, 'https:')
Selfreliant answered 10/1, 2014 at 0:7 Comment(0)
S
16

How about this?

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

Ideally you'd do it on the server side, though.

Servile answered 18/1, 2011 at 11:3 Comment(2)
it's missing the portIndoxyl
and search / query string alsoPandemic
T
12

You should check this: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests

Add this meta tag to your index.html inside head

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

Hope it helped.

Trickery answered 4/3, 2020 at 9:42 Comment(2)
Much more elegant solution when you do not have control of the code being sun on the page (html from a db for instance). We had a gravatar insecure connection and this solved everything.Gleeson
Works great, with one minor caveat--on the very first load the index page is left on http and not reloaded until you navigate again. Tested in incognito mode. It was a problem for my single page front-end which was CORS blocked as it was not immediately on HTTPS.Battology
P
5

Not a Javascript way to answer this but if you use CloudFlare you can write page rules that redirect the user much faster to HTTPS and it's free. Looks like this in CloudFlare's Page Rules:

enter image description here

Piss answered 2/1, 2016 at 7:10 Comment(1)
I actually found this very useful, not for answering the question as framed, but for providing useful information about a possibly more reliable way for a SaaS service that does not offer always-on SSL.Ratha
V
4

You can do:

  <script type="text/javascript">        
        if (window.location.protocol != "https:") {
           window.location.protocol = "https";
        }
    </script>
Vikki answered 24/7, 2019 at 0:45 Comment(1)
It works. Is it a standard way to redirect? will it work in all browsers?Woodall
E
4

I like the answers for this question. But to be creative, I would like to share one more way:

<script>if (document.URL.substring(0,5) == "http:") window.location.replace('https:' + document.URL.substring(5));</script>
Enugu answered 20/12, 2019 at 3:29 Comment(0)
M
3

The below code assumes that the variable 'str' contains your http://.... string. It checks to see if it is https and if true does nothing. However if it is http it replaces http with https.

if (str.indexOf('https') === -1) {
  str = str.replace('http', 'https')
}
Milesmilesian answered 20/6, 2020 at 23:15 Comment(2)
While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.Plywood
This answer is related to this question. #11301406Eskew
E
2

Functional way

window.location.protocol === 'http:' && (location.href = location.href.replace(/^http:/, 'https:'));
Enlistment answered 27/6, 2019 at 13:47 Comment(1)
I like it!! Double quotes are sexier to me like a HUG! Love ur answerEnugu
A
-2

Hi i used this solution works perfectly.No Need to check, just use https.

<script language="javascript" type="text/javascript">
document.location="https:" + window.location.href.substring(window.location.protocol.length, window.location.href.length);
</script>
Actinometer answered 6/8, 2016 at 12:35 Comment(1)
wont this refresh the page even if the protocol is https?Notation
L
-2

I have just had all the script variations tested by Pui Cdm, included answers above and many others using php, htaccess, server configuration, and Javascript, the results are that the script

<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> 

provided by vivek-srivastava works best and you can add further security in java script.

Layla answered 19/6, 2017 at 12:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.