Jak wykryć połączenie internetowe w JavaScript w trybie offline?
Jak wykryć połączenie internetowe w JavaScript w trybie offline?
Odpowiedzi:
Możesz ustalić, że połączenie zostało utracone, wykonując nieudane żądania XHR .
Standardowym podejściem jest ponowienie próby kilka razy. Jeśli nie przejdzie, powiadom użytkownika, aby sprawdził połączenie i z wdziękiem się nie powiedzie .
Sidenote: Ustawienie całej aplikacji w trybie „offline” może prowadzić do wielu podatnych na błędy prac związanych z obsługą stanu. Połączenia bezprzewodowe mogą przychodzić i odchodzić itp. Dlatego najlepszym rozwiązaniem może być po prostu wdzięczne niepowodzenie, zachowanie dane i powiadom użytkownika, pozwalając mu ostatecznie rozwiązać problem z połączeniem, jeśli taki istnieje, i kontynuować korzystanie z aplikacji z dużą dozą przebaczenia.
Sidenote: Możesz sprawdzić wiarygodną witrynę, taką jak Google, pod kątem łączności, ale może to nie być całkiem przydatne, jak próba złożenia własnego żądania, ponieważ chociaż Google może być dostępny, Twoja aplikacja może nie być, a nadal będziesz poradzić sobie z własnym problemem z połączeniem Próba wysłania polecenia ping do Google byłaby dobrym sposobem na potwierdzenie, że samo połączenie internetowe jest niedostępne, więc jeśli ta informacja jest dla Ciebie przydatna, być może warto.
Sidenote : Wysłanie Pinga można osiągnąć w taki sam sposób, jak w przypadku dowolnego dwukierunkowego żądania ajax, ale w tym przypadku wysłanie pinga do Google stanowiłoby pewne wyzwanie. Po pierwsze, mielibyśmy te same problemy między domenami, które zwykle występują przy tworzeniu komunikacji Ajax. Jedną z opcji jest skonfigurowanie serwera proxy po stronie serwera, w którym faktycznie ping
google (lub jakakolwiek inna strona) i zwracamy wyniki ping do aplikacji. To jest catch-22ponieważ jeśli połączenie internetowe stanowi problem, nie będziemy w stanie uzyskać dostępu do serwera, a jeśli problem z połączeniem dotyczy tylko naszej własnej domeny, nie będziemy w stanie stwierdzić różnicy. Można wypróbować inne techniki między domenami, na przykład osadzenie iframe na stronie, która wskazuje na google.com, a następnie sondowanie iframe pod kątem sukcesu / niepowodzenia (sprawdź zawartość itp.). Osadzanie obrazu może nam niewiele powiedzieć, ponieważ potrzebujemy użytecznej odpowiedzi od mechanizmu komunikacji, aby wyciągnąć dobre wnioski na temat tego, co się dzieje. Zatem ponownie określenie stanu połączenia internetowego jako całości może być większym problemem niż jest to warte. Będziesz musiał rozważyć te opcje dla konkretnej aplikacji.
IE 8 będzie obsługiwał window.navigator.onLine właściwość .
Ale to oczywiście nie pomaga w przypadku innych przeglądarek lub systemów operacyjnych. Przewiduję, że inni dostawcy przeglądarek również zdecydują się na udostępnienie tej właściwości, biorąc pod uwagę znaczenie znajomości statusu online / offline w aplikacjach Ajax.
Dopóki to nie nastąpi, albo XHR lub Image()
lub<img>
żądanie może zapewnić coś zbliżonego do pożądanej funkcjonalności.
Aktualizacja (2014/11/16)
Duże przeglądarki obsługują teraz tę właściwość, ale wyniki będą się różnić.
Cytat z dokumentacji Mozilli :
W przeglądarce Chrome i Safari, jeśli przeglądarka nie może połączyć się z siecią lokalną (LAN) lub routerem, jest offline; wszystkie pozostałe warunki powracają
true
. Chociaż można założyć, że przeglądarka jest offline, gdy zwracafalse
wartość, nie można założyć, że prawdziwa wartość musi koniecznie oznaczać, że przeglądarka może uzyskać dostęp do Internetu. Możliwe, że otrzymujesz fałszywe alarmy, na przykład w przypadku, gdy na komputerze jest uruchomione oprogramowanie do wirtualizacji z wirtualnymi adapterami Ethernet, które są zawsze „połączone”. Dlatego jeśli naprawdę chcesz ustalić status online przeglądarki, powinieneś opracować dodatkowe sposoby sprawdzania.W Firefox i Internet Explorer przełączenie przeglądarki do trybu offline powoduje wysłanie
false
wartości. Wszystkie pozostałe warunki zwracajątrue
wartość.
Prawie wszystkie główne przeglądarki obsługują teraz tę window.navigator.onLine
właściwość, a odpowiednie zdarzenia okna online
i offline
:
window.addEventListener('online', () => console.log('came online'));
window.addEventListener('offline', () => console.log('came offline'));
Spróbuj ustawić system lub przeglądarkę w trybie offline / online i sprawdź konsolę lub window.navigator.onLine
właściwość pod kątem zmian wartości. Możesz to również przetestować na tej stronie .
Zwróć jednak uwagę na ten cytat z Dokumentacji Mozilli :
W przeglądarce Chrome i Safari, jeśli przeglądarka nie może połączyć się z siecią lokalną (LAN) lub routerem, jest offline; wszystkie pozostałe warunki powracają
true
. Chociaż można założyć, że przeglądarka jest w trybie offline, gdy zwracafalse
wartość , nie można założyć, żetrue
wartość koniecznie oznacza, że przeglądarka może uzyskać dostęp do Internetu . Możliwe, że otrzymujesz fałszywe alarmy, na przykład w przypadku, gdy na komputerze jest uruchomione oprogramowanie do wirtualizacji z wirtualnymi adapterami Ethernet, które są zawsze „połączone”. Dlatego jeśli naprawdę chcesz ustalić status online przeglądarki, powinieneś opracować dodatkowe sposoby sprawdzania.W Firefox i Internet Explorer przełączenie przeglądarki do trybu offline powoduje wysłanie
false
wartości. Do Firefoksa 41 wszystkie pozostałe warunki zwracajątrue
wartość; od przeglądarki Firefox 41 w systemach OS X i Windows wartość będzie odpowiadać rzeczywistej łączności sieciowej.
(nacisk jest mój)
Oznacza to, że jeśli window.navigator.onLine
jest false
(lub dostaniesz offline
zdarzenie), masz gwarancję, że nie masz połączenia z Internetem.
Jeśli tak jest true
(lub dostaniesz online
zdarzenie), oznacza to, że system jest w najlepszym razie podłączony do jakiejś sieci. Nie oznacza to na przykład, że masz dostęp do Internetu. Aby to sprawdzić, nadal będziesz musiał skorzystać z jednego z rozwiązań opisanych w innych odpowiedziach.
Początkowo zamierzałem opublikować to jako aktualizację odpowiedzi Granta Wagnera , ale wydawało się to zbyt dużą edycją, zwłaszcza biorąc pod uwagę, że aktualizacja 2014 nie była już od niego .
Można to zrobić na kilka sposobów:
Możesz umieścić onerror
w img
, jak
<img src='http://www.example.com/singlepixel.gif'
onerror='alert("Connection dead");' />
Ta metoda mogłaby również zawieść, jeśli obraz źródłowy został przeniesiony / zmieniono jego nazwę, i ogólnie byłby gorszym wyborem niż opcja ajax.
Istnieje więc kilka różnych sposobów na wykrycie tego, żaden z nich nie jest idealny, ale przy braku możliwości wyskoczenia z piaskownicy przeglądarki i uzyskania bezpośredniego dostępu do stanu połączenia sieciowego użytkownika, wydają się być najlepszymi opcjami.
if(navigator.onLine){
alert('online');
} else {
alert('offline');
}
Można użyć $ .ajax () „s error
zwrotna, która pożary, jeżeli żądanie nie powiedzie się. Jeśli textStatus
jest równy ciągowi „limit czasu”, prawdopodobnie oznacza to, że połączenie zostało zerwane:
function (XMLHttpRequest, textStatus, errorThrown) {
// typically only one of textStatus or errorThrown
// will have info
this; // the options for this ajax request
}
Z dokumentu :
Błąd : funkcja, która ma zostać wywołana, jeśli żądanie nie powiedzie się. Do funkcji przekazywane są trzy argumenty: obiekt XMLHttpRequest, ciąg znaków opisujący typ błędu, który wystąpił, oraz opcjonalny obiekt wyjątku, jeśli taki wystąpił. Możliwe wartości dla drugiego argumentu (oprócz null) to „limit czasu”, „błąd”, „niezmodyfikowany” i „parsererror”. To jest wydarzenie Ajax
Na przykład:
$.ajax({
type: "GET",
url: "keepalive.php",
success: function(msg){
alert("Connection active!")
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
if(textStatus == 'timeout') {
alert('Connection seems dead!');
}
}
});
Jak powiedział olliej, korzystanie z navigator.onLine
właściwości przeglądarki jest lepsze niż wysyłanie żądań sieciowych i, zgodnie z developer.mozilla.org/En/Online_and_offline_events , jest nawet obsługiwane przez starsze wersje Firefox i IE.
Ostatnio WHATWG określiło dodanie zdarzeń online
i offline
, na wypadek, gdybyś musiał zareagować na navigator.onLine
zmiany.
Proszę również zwrócić uwagę na link opublikowany przez Daniela Silveirę, który wskazuje, że poleganie na tych sygnałach / właściwościach do synchronizacji z serwerem nie zawsze jest dobrym pomysłem.
window.navigator.onLine
to jest to, czego szukasz, ale tutaj jest kilka rzeczy, które należy dodać, jeśli chcesz coś sprawdzić w swojej aplikacji (na przykład sprawdzić, czy użytkownik nagle przejdzie w tryb offline, co w tym przypadku jest poprawne przez większość czasu) trzeba także posłuchać zmiany), aby dodać detektor zdarzeń do okna w celu wykrycia każdej zmiany, aby sprawdzić, czy użytkownik przejdzie w tryb offline, możesz:
window.addEventListener("offline",
()=> console.log("No Internet")
);
i do sprawdzenia, czy online:
window.addEventListener("online",
()=> console.log("Connected Internet")
);
onLine
. Przeglądarki definiują stan bycia online bardzo różnie. Zajrzyj na developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine/onLine .
Musiałem stworzyć aplikację internetową (opartą na ajax) dla klienta, który dużo współpracuje ze szkołami, szkoły te często mają złe połączenie internetowe. Używam tej prostej funkcji do wykrycia, czy istnieje połączenie, działa bardzo dobrze!
Używam CodeIgniter i Jquery:
function checkOnline() {
setTimeout("doOnlineCheck()", 20000);
}
function doOnlineCheck() {
//if the server can be reached it returns 1, other wise it times out
var submitURL = $("#base_path").val() + "index.php/menu/online";
$.ajax({
url : submitURL,
type : "post",
dataType : "msg",
timeout : 5000,
success : function(msg) {
if(msg==1) {
$("#online").addClass("online");
$("#online").removeClass("offline");
} else {
$("#online").addClass("offline");
$("#online").removeClass("online");
}
checkOnline();
},
error : function() {
$("#online").addClass("offline");
$("#online").removeClass("online");
checkOnline();
}
});
}
wywołanie ajax do Twojej domeny jest najprostszym sposobem na wykrycie, czy jesteś offline
$.ajax({
type: "HEAD",
url: document.location.pathname + "?param=" + new Date(),
error: function() { return false; },
success: function() { return true; }
});
tylko po to, aby dać ci koncepcję, należy ją ulepszyć.
Np. Błąd = 404 powinien nadal oznaczać, że jesteś online
Myślę, że to bardzo prosty sposób.
var x = confirm("Are you sure you want to submit?");
if (x) {
if (navigator.onLine == true) {
return true;
}
alert('Internet connection is lost');
return false;
}
return false;
if the browser is not able to connect to a local area network (LAN) or a router, it is offline; all other conditions return true
Szukałem rozwiązania po stronie klienta, aby wykryć, czy Internet nie działa lub czy mój serwer nie działa. Inne rozwiązania, które zawsze znajdowałem, wydawały się zależeć od pliku skryptu lub obrazu innej firmy, co nie wydawało mi się, żeby wytrzymało próbę czasu. Zewnętrzny hostowany skrypt lub obraz może w przyszłości ulec zmianie i spowodować awarię kodu wykrywającego.
Znalazłem sposób, aby to wykryć, szukając xhrStatus z kodem 404. Ponadto używam JSONP do ominięcia ograniczenia CORS. Kod stanu inny niż 404 pokazuje, że połączenie internetowe nie działa.
$.ajax({
url: 'https://www.bing.com/aJyfYidjSlA' + new Date().getTime() + '.html',
dataType: 'jsonp',
timeout: 5000,
error: function(xhr) {
if (xhr.status == 404) {
//internet connection working
}
else {
//internet is down (xhr.status == 0)
}
}
});
Moja droga.
<!-- the file named "tt.jpg" should exist in the same directory -->
<script>
function testConnection(callBack)
{
document.getElementsByTagName('body')[0].innerHTML +=
'<img id="testImage" style="display: none;" ' +
'src="tt.jpg?' + Math.random() + '" ' +
'onerror="testConnectionCallback(false);" ' +
'onload="testConnectionCallback(true);">';
testConnectionCallback = function(result){
callBack(result);
var element = document.getElementById('testImage');
element.parentNode.removeChild(element);
}
}
</script>
<!-- usage example -->
<script>
function myCallBack(result)
{
alert(result);
}
</script>
<a href=# onclick=testConnection(myCallBack);>Am I online?</a>
Problem niektórych metod, takich jak navigator.onLine
to, że nie są one kompatybilne z niektórymi przeglądarkami i wersjami mobilnymi, opcja, która bardzo mi pomogła, to użycie klasycznej XMLHttpRequest
metody, a także przewidzenie możliwego przypadku, że plik był przechowywany w pamięci podręcznej z odpowiedzią XMLHttpRequest.status
większą niż 200 i mniej niż 304.
Oto mój kod:
var xhr = new XMLHttpRequest();
//index.php is in my web
xhr.open('HEAD', 'index.php', true);
xhr.send();
xhr.addEventListener("readystatechange", processRequest, false);
function processRequest(e) {
if (xhr.readyState == 4) {
//If you use a cache storage manager (service worker), it is likely that the
//index.php file will be available even without internet, so do the following validation
if (xhr.status >= 200 && xhr.status < 304) {
console.log('On line!');
} else {
console.log('Offline :(');
}
}
}
Istnieją dwie odpowiedzi dla dwóch różnych senariów: -
Jeśli używasz JavaScript na stronie internetowej (tj; lub jakiejkolwiek części front-end) Najprostszym sposobem na to jest:
<h2>The Navigator Object</h2>
<p>The onLine property returns true if the browser is online:</p>
<p id="demo"></p>
<script>
document.getElementById("demo").innerHTML = "navigator.onLine is " + navigator.onLine;
</script>
Ale jeśli używasz js po stronie serwera (tj. Węzła itp.), Możesz ustalić, że połączenie zostało zerwane przez wykonanie nieudanych żądań XHR.
Standardowym podejściem jest ponowienie próby kilka razy. Jeśli nie przejdzie, powiadom użytkownika, aby sprawdził połączenie i z wdziękiem się nie powiedzie.
błąd żądania żądania
$.ajax({
url: /your_url,
type: "POST or GET",
data: your_data,
success: function(result){
//do stuff
},
error: function(xhr, status, error) {
//detect if user is online and avoid the use of async
$.ajax({
type: "HEAD",
url: document.location.pathname,
error: function() {
//user is offline, do stuff
console.log("you are offline");
}
});
}
});
Oto fragment narzędzia pomocniczego, które mam. To jest javascript z przestrzenią nazw:
network: function() {
var state = navigator.onLine ? "online" : "offline";
return state;
}
Powinieneś używać tego z wykrywaniem metod, w przeciwnym razie uruchom „alternatywny” sposób na wykonanie tego. Zbliża się czas, kiedy będzie to wszystko, czego potrzeba. Inne metody to hacki.