Puteți utiliza JavaScript pentru a verifica dacă aplicația dvs. este conectată la internet?

În acest articol, voi oferi un răspuns actualizat la această întrebare de detectare a conexiunii la Internet. (Vai! Spune asta repede de cinci ori!)

Soluția va utiliza API-ul Fetch JavaScript și codul asincron cu Async & Await. Dar mai întâi, să analizăm o soluție acceptată și să discutăm de ce poate să nu fie cea mai bună alegere pentru aplicația dvs.

Proprietatea online a interfeței de navigare, navigator.onLine, este frecvent utilizat pentru a detecta starea online și offline a browserului.

Combinat cu ascultători pentru evenimente online și offline, pare să ofere o soluție simplă pentru dezvoltatori ușor de implementat.

Să vedem cum vom implementa navigator.onLine

Începeți prin adăugarea unui ascultător de evenimente de încărcare. Când evenimentul de încărcare se declanșează, ascultătorul va verifica proprietatea online a interfeței navigatorului și apoi va afișa starea online.

Proprietatea online a navigatorului oferă un răspuns boolean (adevărat sau fals). Pentru a finaliza acțiunea ascultătorului, vom folosi o declarație ternară pentru a seta valoarea afișării stării.

window.addEventListener("load", (event) => {
  const statusDisplay = document.getElementById("status");
  statusDisplay.textContent = navigator.onLine ? "Online" : "OFFline";
});

Deci, de ce cuvântul navigator? Ei bine, este o referință la browserul Netscape Navigator din anii ’90.

Centrați un element h1 în pagina dvs. HTML cu ID-ul „status”. Dacă aplicați codul JavaScript de mai sus paginii dvs., ar trebui să îl vedeți afișat „Online”.

Dar acest lucru actualizează elementul h1 doar când pagina se încarcă. Să adăugăm ascultători de evenimente offline și online pentru a actualiza afișarea stării oricând se declanșează oricare dintre aceste evenimente.

window.addEventListener("offline", (event) => {
  const statusDisplay = document.getElementById("status");
  statusDisplay.textContent = "OFFline";
});

window.addEventListener("online", (event) => {
  const statusDisplay = document.getElementById("status");
  statusDisplay.textContent = "Online";
});

Putem accesa fila Aplicații din Chrome Dev Tools și putem face clic pe ServiceWorker pentru a seta browserul să răspundă ca și cum ar fi offline.

Bifați și debifați caseta de selectare Offline de câteva ori. Ar trebui să vedeți afișarea stării să răspundă imediat la evenimentele offline și online declanșate.

Cum se verifica starea conexiunii la Internet folosind JavaScript Async
Instrumente de dezvoltare Chrome> fila Aplicații> Lucrători de servicii> Casetă de selectare offline

Să sapăm puțin mai adânc

La prima impresie, cele de mai sus par o soluție bună, care este destul de simplă. Din păcate, pe măsură ce citim mai multe despre proprietatea online a navigatorului și despre evenimentele online și offline, constatăm că există o problemă.

Căutarea navigator.onLine pe CanIUse.com arată un sprijin larg pentru online | starea offline pe care o oferă proprietatea. Cu toate acestea, uitându-ne la notele de sub tabelul de asistență, vedem asta

„Online nu înseamnă întotdeauna conectarea la Internet. De asemenea, poate însemna doar conectarea la o anumită rețea ”.

Hmm, asta aruncă puțin o cheie în lucrări.

Deci, dacă doriți cu adevărat să determinați starea online a browserului, ar trebui să dezvoltați mijloace suplimentare pentru verificare.

Să aruncăm o privire și asupra Referință documente MDN pentru navigator.onLine. Documentele web MDN fac backup pentru informațiile CanIUse.com și adaugă note suplimentare.

„Browserele implementează această proprietate diferit … nu puteți presupune că o valoare adevărată înseamnă neapărat că browserul poate accesa internetul. S-ar putea să obțineți falsuri pozitive … ”

Și asta confirmă temerile noastre cu privire la utilizarea proprietății online a navigatorului ca soluție pentru detectarea unei conexiuni la Internet. Este o soluție care poate face ravagii în aplicațiile noastre, care depind de a ști când sunt disponibile surse de date externe.

Un astfel de exemplu este atunci când încercăm să stabilim dacă o aplicație web progresivă este online sau nu. MDN recomandă chiar,

„… dacă doriți cu adevărat să determinați starea online a browserului, ar trebui să dezvoltați mijloace suplimentare pentru verificare.”

O căutare rapidă pe web pentru „Navigatorul online nu funcționează” dezvăluie diverse postări pe forum în care cei care depind de această proprietate au întâmpinat probleme.

Deci, care este soluția?

Trebuie să știm când aplicația noastră este cu adevărat conectată la Internet și nu doar la un router sau la o rețea locală. Să ne întoarcem la fișierul nostru JavaScript și să o luăm de la capăt.

Ideea este să faceți o cerere și să o gestionați cu grație, prin prinderea erorilor, dacă nu reușește. Dacă solicitarea reușește, suntem online și, dacă nu reușește, nu suntem.

Vom solicita o imagine mică la un interval pentru a determina starea online. JavaScript modern oferă API-ul Fetch și codul asincron cu Async & Await. Vom folosi aceste instrumente pentru a ne atinge obiectivul.

checkOnlineStatus ()

Să începem prin a crea o funcție săgeată asincronizată numită checkOnlineStatus. Funcția va returna adevărat sau fals, așa cum face proprietatea online a navigatorului.

În interiorul funcției, vom configura un bloc de încercare în care așteptăm o cerere de preluare pentru o imagine de un pixel. Asigurați-vă că lucrătorul dvs. de service nu cache această imagine.

Codurile de răspuns HTTP între 200 și 299 indică succesul și vom returna rezultatul comparării codului de stare. Acest lucru va fi adevărat dacă starea răspunsului este de la 200 la 299 și falsă în caz contrar.

De asemenea, trebuie să furnizăm un bloc de captură care detectează eroarea dacă solicitarea eșuează. Vom returna false în blocul de captură pentru a indica că suntem cu siguranță offline dacă se întâmplă acest lucru.

const checkOnlineStatus = async () => {
  try {
    const online = await fetch("/1pixel.png");
    return online.status >= 200 && online.status < 300; // either true or false
  } catch (err) {
    return false; // definitely offline
  }
};

Apoi, vom folosi metoda setInterval și îi vom transmite o funcție asincronă anonimă. Funcția asincronă va aștepta rezultatul funcției noastre checkOnlineStatus. Vom folosi apoi o declarație ternară cu rezultatul pentru a afișa starea curentă online.

Pentru testarea acestui exemplu, setați intervalul de întârziere la fiecare 3 secunde (3000 milisecunde). Totuși, acest lucru este prea des. Verificarea la fiecare 30 de secunde (30000 milisecunde) poate fi suficientă pentru nevoile dvs. reale.

setInterval(async () => {
  const result = await checkOnlineStatus();
  const statusDisplay = document.getElementById("status");
  statusDisplay.textContent = result ? "Online" : "OFFline";
}, 3000); // probably too often, try 30000 for every 30 seconds

Cu noul nostru cod salvat, să revenim la fila Aplicație din Chrome Dev Tools pentru a testa răspunsul offline.

1612033627 742 Cum se verifica starea conexiunii la Internet folosind JavaScript Async
Instrumente de dezvoltare Chrome> fila Aplicații> Lucrători de servicii> Casetă de selectare offline

Aproape că am uitat să includ ascultătorul de evenimente de încărcare cu funcționalitate asincronizată! Detectarea evenimentelor de încărcare este probabil importantă numai dacă aveți o aplicație web progresivă care utilizează un lucrător de service pentru disponibilitate offline. În caz contrar, pagina dvs. web sau aplicația pur și simplu nu se vor încărca fără o conexiune.

Iată noul ascultător de evenimente de încărcare:

window.addEventListener("load", async (event) => {
  const statusDisplay = document.getElementById("status");
  statusDisplay.textContent = (await checkOnlineStatus())
    ? "Online"
    : "OFFline";
});

Un gând final

Codul de interval de mai sus este bun pentru afișarea stării conexiunii în aplicația dvs. Acestea fiind spuse, nu vă recomand să vă bazați pe o stare a conexiunii care a fost verificată cu 20 sau 30 de secunde înainte de a face o cerere de date critice în aplicația dvs.

Prin urmare, trebuie să apelați funcția checkOnlineStatus direct înainte de solicitare și să evaluați răspunsul înainte de a solicita date.

const yourDataRequestFunction = async () => {
    const online = await checkOnlineStatus();
    if (online) {
    	// make data request
    }
}

Concluzie

În timp ce navigator.onLine este acceptat pe scară largă, acesta oferă rezultate nesigure când se determină dacă aplicațiile noastre sunt cu adevărat conectate la Internet. Folosind API-ul Fetch și JavaScript asincron, putem codifica rapid o soluție mai fiabilă.

Iată un link către esența codului pe GitHub și iată un tutorial video pe care l-am pus împreună: