Detecta HTTP o HTTPS y luego fuerza HTTPS en JavaScript

298

¿Hay alguna forma de detectar HTTP o HTTPS y luego forzar el uso de HTTPS con JavaScript?

Tengo algunos códigos para detectar HTTP o HTTPS pero no puedo forzarlo a usar https:.

Estoy usando la propiedad window.location.protocol para establecer lo que sea el sitio para https:luego actualizar la página y, con suerte, volver a cargar una nueva URL https cargada en el navegador.

if (window.location.protocol != "https:") {
   window.location.protocol = "https:";
   window.location.reload();
}
usuario registrado
fuente
15
Esto se maneja de manera mucho más confiable (y eficiente) en el lado del servidor.
Quentin
3
Creo que tienes razón. Como atacante que usa un ataque MITM, podría eliminar este código. Por lo tanto, solo ofrece protección contra ataques pasivos.
ndevln
La parte de detección es un duplicado de ¿Cómo puedo usar JavaScript en el lado del cliente para detectar si la página estaba encriptada? desde 2008.
Dan Dascalescu
1
@NeoDevlin, un atacante MITM en http también puede reemplazar una redirección del lado del servidor
Alex Lehmann
1
Exactamente. En 2018, no hay excusa para no usar HSTS. Esta es la única forma segura de forzar HTTPS.

Respuestas:

501

Prueba esto

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

location.href = blahagrega esta redirección al historial del navegador. Si el usuario presiona el botón Atrás, será redirigido a la misma página. Es mejor usarlo location.replaceya que no agrega esta redirección al historial del navegador.

Soumya
fuente
3
¿Por qué windowy no document?
webjay
11
¿Debería ser la comparación de cadenas !==?
Wes Turner
55
@WesTurner No debería importar de ninguna manera. Ambos siempre serán cuerdas. Si uno fuera un número o un booleano, entonces podría hacer la diferencia.
Soumya
15
location.replace(url)Sería mucho mejor que location.href = urlpara este caso. No desea esta redirección en el historial del navegador o que el usuario presione el botón Atrás para ser redirigido nuevamente.
Francisco Zarabozo
59

Establecer location.protocol navega a una nueva URL . No es necesario analizar / cortar nada.

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

Firefox 49 tiene un error donde httpsfunciona pero https:no funciona. Se dice que se arreglará en Firefox 54 .

sam
fuente
2
if window.location.href.match('http:') window.location.href = window.location.href.replace('http', 'https')funciona en los últimos FF y Chrome.
Martin Stannard
2
location.protocol = "https";parece funcionar en
Firefox
1
Mierda que rompe el botón de retroceso. Usar en su location.replacelugar.
Warlike Chimpanzee
22

No es una buena idea porque solo redirige temporalmente al usuario a https y el navegador no guarda esta redirección.

Describe la tarea para el servidor web (apache, nginx, etc.) http 301, http 302

b1_
fuente
3
de acuerdo. Forzar https en el servidor es mucho más confiable
Hoàng Long
3
Podría ver que se usa si es importante preservar el valor hash. No se envía al servidor y algunos navegadores no lo conservan.
Jason Rice
Aquí hay un enlace para configurar el sitio web de Azure solo para https ... blogs.msdn.com/b/benjaminperkins/archive/2014/01/07/…
OzBob
1
No necesariamente cierto. Hay una escuela de pensamiento de que 301 es el demonio por razones de almacenamiento en caché. getluky.net/2010/12/14/301-redirects-cannot-be-undon
fivedogit
2
Si bien es cierto que generalmente no es una buena idea hacer este lado del cliente, esto no es lo que se le pidió. Y no muestra cómo hacerlo, por lo tanto, esto no es una respuesta. Además, en estos días de páginas web estáticas, a menudo no hay forma de hacer este lado del servidor (piense en las páginas de Github), lo que significa que debe hacerlo en el cliente. Aún así, puede ayudar a mejorar la búsqueda agregando etiquetas de enlace canónicas para evitar que las personas accedan a la versión que no es SSL.
oligofren
16

¿Qué tal esto?

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

Sin embargo, lo ideal sería hacerlo en el lado del servidor.

keirog
fuente
le falta el puerto
eadmaster
13
if (location.protocol == 'http:')
  location.href = location.href.replace(/^http:/, 'https:')
Steven Penny
fuente
5

No es una forma de Javascript para responder esto, pero si usa CloudFlare, puede escribir reglas de página que redirijan al usuario mucho más rápido a HTTPS y es gratis. Se ve así en las reglas de la página de CloudFlare:

ingrese la descripción de la imagen aquí

Mikeumus
fuente
De hecho, esto me pareció muy útil, no para responder la pregunta como enmarcada, sino para proporcionar información útil sobre una forma posiblemente más confiable para un servicio SaaS que no ofrece SSL siempre activo.
MrMesees
3

Tu puedes hacer:

  <script type="text/javascript">        
        if (window.location.protocol != "https:") {
           window.location.protocol = "https";
        }
    </script>
M.BRAHAM
fuente
Funciona. ¿Es una forma estándar de redirigir? ¿funcionará en todos los navegadores?
mahfuz
1

Forma funcional

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

Me gustan las respuestas a esta pregunta. Pero para ser creativo, me gustaría compartir una forma más:

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

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

Código Laymans
fuente
2
Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a cómo y / o por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta.
Pato Donald
-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
fuente
-1

Hola, utilicé esta solución funciona perfectamente. No es necesario verificar, solo use https.

<script language="javascript" type="text/javascript">
document.location="https:" + window.location.href.substring(window.location.protocol.length, window.location.href.length);
</script>
BrAiNee
fuente
3
¿Esto no actualizará la página incluso si el protocolo es https?
Anthony
-2

Acabo de probar todas las variaciones de script probadas por Pui Cdm , incluí las respuestas anteriores y muchas otras usando php, htaccess, configuración del servidor y Javascript, los resultados son que el 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> 

proporcionado por vivek-srivastava funciona mejor y puede agregar más seguridad en el script java.

Peter
fuente