Wykryj HTTP lub HTTPS, a następnie wymuś HTTPS w JavaScript

298

Czy jest jakiś sposób na wykrycie HTTP lub HTTPS, a następnie wymuszenie użycia HTTPS z JavaScript?

Mam pewne kody do wykrywania HTTP lub HTTPS, ale nie mogę zmusić go do użycia https:.

Korzystam z właściwości window.location.protocol, aby ustawić dowolną witrynę, https:a następnie odświeżyć stronę i, mam nadzieję, ponownie załadować nowy adres URL https załadowany do przeglądarki.

if (window.location.protocol != "https:") {
   window.location.protocol = "https:";
   window.location.reload();
}
zarejestrowany użytkownik
źródło
15
Jest to o wiele bardziej niezawodnie (i wydajniej) obsługiwane po stronie serwera.
Quentin,
3
Myślę, że masz rację. Jako atakujący wykorzystujący atak MITM mógłbym po prostu usunąć ten kod. Oferuje więc tylko ochronę przed atakami pasywnymi.
ndevln
Część wykrywająca jest duplikatem Jak mogę użyć JavaScript po stronie klienta, aby wykryć, czy strona została zaszyfrowana? od 2008 r.
Dan Dascalescu,
1
@NeoDevlin atakujący MITM na http może również zastąpić przekierowanie po stronie serwera
Alex Lehmann
1
Dokładnie. W 2018 roku nie ma wymówki, aby nie używać HSTS. Jest to jedyny bezpieczny sposób na wymuszenie HTTPS.

Odpowiedzi:

500

Spróbuj tego

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

location.href = blahdodaje to przekierowanie do historii przeglądarki. Jeśli użytkownik naciśnie przycisk Wstecz, zostanie przekierowany z powrotem na tę samą stronę. Lepiej jest używać, location.replaceponieważ nie dodaje tego przekierowania do historii przeglądarki.

Soumya
źródło
3
Dlaczego windownie document?
webjay,
11
Czy powinno być porównanie ciągów !==?
Wes Turner,
5
@WesTurner To nie powinno mieć znaczenia. Oboje zawsze będą sznurkami. Jeśli jeden był liczbą lub wartością logiczną, może to mieć znaczenie.
Soumya
15
location.replace(url)byłoby znacznie lepiej niż location.href = urlw tym przypadku. Nie chcesz, aby to przekierowanie w historii przeglądarki lub użytkownik naciskał przycisk Wstecz, aby ponownie zostać przekierowanym.
Francisco Zarabozo
58

Ustawienie location.protocol powoduje przejście do nowego adresu URL . Nie trzeba parsować / kroić niczego.

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

Firefox 49 ma błąd, w którym httpsdziała, ale https:nie działa. Podobno zostanie naprawiony w Firefox 54 .

sam
źródło
2
if window.location.href.match('http:') window.location.href = window.location.href.replace('http', 'https')działa na najnowszych FF i Chrome.
Martin Stannard,
2
location.protocol = "https";wydaje się, że działa w Firefox 28
Nick Russler
1
Bzdura, która łamie przycisk Wstecz. Użyj location.replacezamiast tego.
Warlike Chimpanzee,
22

To nie jest dobry pomysł, ponieważ chwilowo przekierowujesz użytkownika do https, a przeglądarka nie zapisuje tego przekierowania.

Opisujesz zadanie dla serwera WWW (apache, nginx itp.) Http 301, http 302

b1_
źródło
3
Zgodzić się. Wymuszanie https na serwerze jest znacznie bardziej niezawodne
Hoàng Long
3
Widziałem, że jest używany, jeśli zachowanie wartości skrótu jest ważne. Nie jest wysyłany na serwer, a niektóre przeglądarki go nie zachowują.
Jason Rice,
Oto link do Ustaw witrynę sieci Web platformy
OzBob
1
Niekoniecznie prawda. Istnieje szkoła myślenia, że ​​301 jest diabłem z powodów buforowania. getluky.net/2010/12/14/301-redirects-cannot-be-undon
fivedogit
2
Chociaż prawdą jest, że generalnie nie jest dobrym pomysłem robić to po stronie klienta, nie o to pytano. I nie pokazujesz, jak to zrobić, dlatego nie jest to odpowiedź. Ponadto w dzisiejszych czasach statycznych stron internetowych często nie ma możliwości zrobienia tego po stronie serwera (pomyśl o stronach Github), co oznacza, że ​​musisz to zrobić na kliencie. Nadal możesz poprawić wyszukiwanie, dodając kanoniczne tagi linków, aby ludzie nie trafili na wersję inną niż ssl.
oligofren
16

Co powiesz na to?

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

Idealnie byłoby to zrobić po stronie serwera.

keirog
źródło
brakuje portu
eadmaster
13
if (location.protocol == 'http:')
  location.href = location.href.replace(/^http:/, 'https:')
Steven Penny
źródło
5

Nie jest to metoda Javascript, aby odpowiedzieć na to pytanie, ale jeśli używasz CloudFlare, możesz pisać reguły strony, które przekierowują użytkownika znacznie szybciej do HTTPS i jest bezpłatne. Wygląda to tak w Regułach strony CloudFlare:

wprowadź opis zdjęcia tutaj

Mikeumus
źródło
Uznałem to za bardzo przydatne, nie do odpowiedzi na pytanie w ramce, ale do dostarczenia użytecznych informacji o prawdopodobnie bardziej niezawodnym sposobie dla usługi SaaS, która nie oferuje zawsze włączonego protokołu SSL.
MrMesees
3

Możesz to zrobić:

  <script type="text/javascript">        
        if (window.location.protocol != "https:") {
           window.location.protocol = "https";
        }
    </script>
M.BRAHAM
źródło
To działa. Czy to standardowy sposób przekierowania? czy będzie działać we wszystkich przeglądarkach?
mafuz
1

Funkcjonalny sposób

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

Lubię odpowiedzi na to pytanie. Ale aby być kreatywnym, chciałbym podzielić się jeszcze jednym sposobem:

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

Cześć, użyłem tego rozwiązania, działa idealnie. Nie trzeba sprawdzać, wystarczy użyć https

<script language="javascript" type="text/javascript">
document.location="https:" + window.location.href.substring(window.location.protocol.length, window.location.href.length);
</script>
BrAiNee
źródło
3
czy to nie odświeży strony nawet jeśli protokołem jest https?
Anthony
-2

Właśnie przetestowałem wszystkie warianty skryptu przetestowane przez Pui Cdm , w tym odpowiedzi powyżej i wiele innych przy użyciu php, htaccess, konfiguracji serwera i Javascript, wyniki są takie, że skrypt

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

dostarczone przez vivek-srivastava działa najlepiej i możesz dodać dodatkowe bezpieczeństwo w skrypcie Java.

Piotr
źródło