Detectar HTTP ou HTTPS e forçar HTTPS em JavaScript

298

Existe alguma maneira de detectar HTTP ou HTTPS e forçar o uso de HTTPS com JavaScript?

Eu tenho alguns códigos para detectar o HTTP ou HTTPS, mas não posso forçá-lo a usar https:.

Estou usando a propriedade window.location.protocol para definir o que quer que seja o site e, em https:seguida, atualize a página para recarregar uma nova URL https'ed carregada no navegador.

if (window.location.protocol != "https:") {
   window.location.protocol = "https:";
   window.location.reload();
}
Usuário Registrado
fonte
15
Isso é muito mais confiável (e eficiente) no lado do servidor.
Quentin
3
Eu acho que você está certo. Como um invasor usando um ataque MITM, eu poderia simplesmente excluir este código. Por isso, oferece apenas proteção contra ataques passivos.
Ndevln
A parte de detecção é uma duplicata de Como posso usar JavaScript no lado do cliente para detectar se a página foi criptografada? de 2008.
Dan Dascalescu 13/07/2015
1
@NeoDevlin um atacante MITM em http pode substituir um redirecionamento do lado do servidor, bem
Alex Lehmann
1
Exatamente. Em 2018, não há desculpa para não usar o HSTS. Essa é a única maneira segura de forçar o HTTPS.

Respostas:

500

Tente isto

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

location.href = blahadiciona esse redirecionamento ao histórico do navegador. Se o usuário pressionar o botão Voltar, ele será redirecionado novamente para a mesma página. É melhor usar location.replace, pois não adiciona esse redirecionamento ao histórico do navegador.

Soumya
fonte
3
Por que windowe não document?
Webjay
11
A comparação de cadeias deve ser !==?
Wes Turner
5
@WesTurner Não deve importar de qualquer maneira. Os dois sempre serão cordas. Se um fosse um número ou um booleano, pode fazer a diferença.
Soumya 14/10
15
location.replace(url)seria muito melhor do que location.href = urlpara este caso. Você não deseja esse redirecionamento no histórico do navegador ou o usuário pressiona o botão Voltar apenas para ser redirecionado novamente.
Francisco Zarabozo
59

A configuração location.protocol navega para um novo URL . Não há necessidade de analisar / cortar nada.

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

O Firefox 49 tem um bug onde httpsfunciona, mas https:não funciona . Dito para ser corrigido no Firefox 54 .

sam
fonte
2
if window.location.href.match('http:') window.location.href = window.location.href.replace('http', 'https')funciona no mais recente FF e Chrome.
Martin Stannard
2
location.protocol = "https";parece funcionar embora no firefox 28
Nick Russler 28/04
1
Porcaria que quebra o botão Voltar. Use em location.replacevez disso.
Chimpanzé guerreiro
22

Não é uma boa ideia, porque você redireciona temporariamente o usuário para https e o navegador não salva esse redirecionamento.

Você descreve a tarefa para o servidor Web (apache, nginx etc) http 301, http 302

b1_
fonte
3
aceita. Forçar https no servidor é muito mais confiável
Hoang Long
3
Eu pude ver isso sendo usado se a preservação do valor do hash for importante. Ele não é enviado ao servidor e alguns navegadores não o preservam.
Jason Arroz
Aqui está um link para Definir o Site do Azure apenas para https ... blogs.msdn.com/b/benjaminperkins/archive/2014/01/07/…
OzBob
1
Não é necessariamente verdade. Existe uma escola de pensamento de que 301 é o diabo por razões de cache. getluky.net/2010/12/14/301-redirects-cannot-be-undon
fivedogit 3/16
2
Embora seja verdade que geralmente não é uma boa ideia fazer esse lado do cliente, não foi isso que foi solicitado. E você não mostra como fazê-lo, portanto, isso não é uma resposta. Além disso, nos dias de páginas estáticas da Web, geralmente não há como fazer isso do lado do servidor (veja as páginas do Github), o que significa que você deve fazer isso no cliente. Ainda assim, você pode ajudar a melhorar a pesquisa adicionando tags de link canônico para evitar que as pessoas cheguem à versão não-ssl.
oligofren
16

Que tal agora?

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

Idealmente, você faria no lado do servidor.

keirog
fonte
está faltando o porto
eadmaster
13
if (location.protocol == 'http:')
  location.href = location.href.replace(/^http:/, 'https:')
Steven Penny
fonte
5

Não é uma maneira Javascript de responder a isso, mas se você usa o CloudFlare, pode escrever regras de página que redirecionam o usuário muito mais rapidamente para HTTPS e é gratuito. É assim nas regras da página do CloudFlare:

insira a descrição da imagem aqui

Mikeumus
fonte
Na verdade, achei isso muito útil, não para responder à pergunta conforme enquadrada, mas para fornecer informações úteis sobre uma maneira possivelmente mais confiável para um serviço SaaS que não oferece SSL sempre ativo.
MrMesees
3

Você pode fazer:

  <script type="text/javascript">        
        if (window.location.protocol != "https:") {
           window.location.protocol = "https";
        }
    </script>
M.BRAHAM
fonte
Funciona. É uma maneira padrão de redirecionar? funcionará em todos os navegadores?
Mahfuz 12/11/19
1

Maneira funcional

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

Eu gosto das respostas para esta pergunta. Mas, para ser criativo, gostaria de compartilhar mais uma maneira:

<script>if (document.URL.substring(0,5) == "http:") {
            window.location.replace('https:' + document.URL.substring(5));
        }
</script>
Charles Hamel
fonte
-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
fonte
-1

Oi eu usei esta solução funciona perfeitamente.Não precisa verificar, basta usar https.

<script language="javascript" type="text/javascript">
document.location="https:" + window.location.href.substring(window.location.protocol.length, window.location.href.length);
</script>
BrAiNee
fonte
3
isso não atualizará a página mesmo se o protocolo for https?
Anthony
-2

Acabei de testar todas as variações de script do Pui Cdm , incluindo as respostas acima e muitas outras usando php, htaccess, configuração do servidor e Javascript; os resultados são que o 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> 

fornecido por vivek-srivastava funciona melhor e você pode adicionar mais segurança no script java.

Peter
fonte