Détectez HTTP ou HTTPS puis forcez HTTPS en JavaScript

298

Existe-t-il un moyen de détecter HTTP ou HTTPS, puis de forcer l'utilisation de HTTPS avec JavaScript?

J'ai quelques codes pour détecter le HTTP ou HTTPS mais je ne peux pas le forcer à utiliser https:.

J'utilise la propriété window.location.protocol pour définir quel que soit le site, https:puis actualiser la page pour, espérons-le, recharger une nouvelle URL https chargée dans le navigateur.

if (window.location.protocol != "https:") {
   window.location.protocol = "https:";
   window.location.reload();
}
Utilisateur enregistré
la source
15
Ceci est géré de manière beaucoup plus fiable (et efficace) côté serveur.
Quentin
3
Je pense que tu as raison. En tant qu'attaquant utilisant une attaque MITM, je pourrais simplement supprimer ce code. Il n'offre donc qu'une protection contre les attaques passives.
ndevln
1
@NeoDevlin un attaquant MITM sur http peut également remplacer une redirection côté serveur
Alex Lehmann
1
Exactement. En 2018, il n'y a aucune excuse pour ne pas utiliser HSTS. C'est le seul moyen sûr de forcer HTTPS.

Réponses:

501

Essaye ça

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

location.href = blahajoute cette redirection à l'historique du navigateur. Si l'utilisateur clique sur le bouton de retour, il sera redirigé vers la même page. Il est préférable de l'utiliser location.replacecar il n'ajoute pas cette redirection à l'historique du navigateur.

Soumya
la source
3
Pourquoi windowet non document?
webjay
11
La comparaison de chaînes doit !==-elle être ?
Wes Turner du
5
@WesTurner Cela ne devrait pas avoir d'importance de toute façon. Ils seront tous les deux toujours des cordes. Si l'un était un nombre ou un booléen, cela pourrait faire une différence.
Soumya
15
location.replace(url)serait bien mieux que location.href = urldans ce cas. Vous ne voulez pas de cette redirection dans l'historique du navigateur ou que l'utilisateur clique sur le bouton de retour juste pour être redirigé à nouveau.
Francisco Zarabozo
59

La définition de location.protocol permet d'accéder à une nouvelle URL . Pas besoin d'analyser / découper quoi que ce soit.

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

Firefox 49 a un bug où ça httpsmarche mais https:pas. Dit être corrigé dans Firefox 54 .

sam
la source
2
if window.location.href.match('http:') window.location.href = window.location.href.replace('http', 'https')fonctionne sur les derniers FF et Chrome.
Martin Stannard
2
location.protocol = "https";semble bien fonctionner dans firefox 28
Nick Russler
1
Merde qui casse le bouton de retour. Utilisez location.replaceplutôt.
Warlike Chimpanzee
22

Ce n'est pas une bonne idée car vous redirigez simplement l' utilisateur vers https temporairement et le navigateur n'enregistre pas cette redirection.

Vous décrivez la tâche pour le serveur web (apache, nginx etc.) http 301, http 302

b1_
la source
3
se mettre d'accord. Forcer https sur le serveur est beaucoup plus fiable
Hoàng Long
3
Je pourrais le voir utilisé si la préservation de la valeur de hachage est importante. Il n'est pas envoyé au serveur et certains navigateurs ne le conservent pas.
Jason Rice
Voici un lien vers Définir le site Web Azure pour https uniquement ... blogs.msdn.com/b/benjaminperkins/archive/2014/01/07/…
OzBob
1
Pas nécessairement vrai. Il existe une école de pensée selon laquelle 301 est le diable pour des raisons de mise en cache. getluky.net/2010/12/14/301-redirects-cannot-be-undon
fivedogit
2
S'il est vrai que ce n'est généralement pas une bonne idée de faire ce côté client, ce n'est pas ce qui a été demandé. Et vous ne montrez pas comment le faire, ce n'est donc pas une réponse. De plus, en ces jours de pages Web statiques, il n'y a souvent aucun moyen de faire ce côté serveur (pensez aux pages Github), ce qui signifie que vous devez le faire sur le client. Néanmoins, vous pouvez aider à améliorer la recherche en ajoutant des balises de lien canoniques pour éviter que les gens n'utilisent la version non SSL.
oligofren
16

Que dis-tu de ça?

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

Idéalement, vous le feriez du côté serveur, cependant.

keirog
la source
il manque le port
eadmaster
13
if (location.protocol == 'http:')
  location.href = location.href.replace(/^http:/, 'https:')
Steven Penny
la source
5

Ce n'est pas un moyen Javascript pour répondre à cela, mais si vous utilisez CloudFlare, vous pouvez écrire des règles de page qui redirigent l'utilisateur beaucoup plus rapidement vers HTTPS et c'est gratuit. Ressemble à ceci dans les règles de page de CloudFlare:

entrez la description de l'image ici

Mikeumus
la source
En fait, j'ai trouvé cela très utile, non pas pour répondre à la question telle que formulée, mais pour fournir des informations utiles sur un moyen peut-être plus fiable pour un service SaaS qui n'offre pas toujours SSL.
MrMesees
3

Tu peux faire:

  <script type="text/javascript">        
        if (window.location.protocol != "https:") {
           window.location.protocol = "https";
        }
    </script>
M.BRAHAM
la source
Ça marche. Est-ce un moyen standard de rediriger? cela fonctionnera-t-il dans tous les navigateurs?
mahfuz
1

Manière fonctionnelle

window.location.protocol === 'http:' && (location.href = location.href.replace(/^http:/, 'https:'));
Дмитрий Васильев
la source
0

J'aime les réponses à cette question. Mais pour être créatif, je voudrais partager une autre façon:

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

Le code ci-dessous suppose que la variable "str" ​​contient votre chaîne http: // ..... Il vérifie si c'est https et si true ne fait rien. Cependant, s'il s'agit de http, il remplace http par https.

if (str.indexOf('https') === -1) {
  str = str.replace('http', 'https')
}

Code Laymans
la source
2
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire sur la manière et / ou la raison pour laquelle il résout le problème améliorerait la valeur à long terme de la réponse.
Donald Duck Il y a
@DonaldDuck Désolé, je pensais que ça allait de soi.
Laymans Code Il y a
-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>
Vivek Srivastava
la source
-1

Salut j'ai utilisé cette solution fonctionne parfaitement. Pas besoin de vérifier, utilisez simplement https.

<script language="javascript" type="text/javascript">
document.location="https:" + window.location.href.substring(window.location.protocol.length, window.location.href.length);
</script>
BrAiNee
la source
3
cela ne rafraîchira-t-il pas la page même si le protocole est https?
Anthony
-2

Je viens de faire tester toutes les variantes de script par Pui Cdm , y compris les réponses ci-dessus et bien d'autres en utilisant php, htaccess, la configuration du serveur et Javascript, les résultats sont que le 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> 

fourni par vivek-srivastava fonctionne mieux et vous pouvez ajouter une sécurité supplémentaire dans le script java.

Peter
la source