2012-03-20 13 views
12

Testuję aplikację offline HTML5. Aby to zrobić, zatrzymuję mój lokalny serwer WWW (IIS) i otwieram aplikację. Ładuje się dobrze, ale nie udało się, gdy tylko zażąda metody API po stronie serwera.HTML5/JS - sprawdź, czy aplikacja jest nieaktywna

Chcę temu zapobiec i zamiast $ .get ("/ api/method") odczytać dane z mojej lokalnej pamięci. Ale mogę znaleźć dowolny obiekt, aby zrozumieć, że moja aplikacja jest w trybie offline.

if (/* online */) { 
    // fire ajax 
} else { 
    // ask localstorage 
} 

Próbowałem użyć navigation.onLine ale wydaje się być zawsze prawdziwe (przynajmniej widzę, że w Chrome).

Czy masz jakieś sugestie?

EDYCJA: uwzględnienie bieżących odpowiedzi. Aplikacja wyraźnie rozumie, że jest offline, ponieważ pobiera zasoby zgodnie z cache.manifest. To dla mnie śmieszne, że klient musi robić wszelkiego rodzaju sztuczki i pingi. Zakładam, że powinien istnieć łatwy sposób sprawdzenia bieżącego trybu.

+0

spróbuj spojrzeć na źródła upshot.js. wdrożyli to zachowanie. – mironych

+2

Nie ma łatwego sposobu sprawdzenia, ponieważ nie ma łatwego sposobu, aby dowiedzieć się, co stanowi "online". Interfejs sieciowy może być podniesiony, urządzenie/komputer może być w sieci, ale jeśli ta sieć nie ma połączenia z Internetem, to czy jesteś online lub offline? To zależy od tego, czy aplikacja jest w Internecie, czy w intranecie. Co się stanie, jeśli masz dostęp do Internetu, ale Twoja aplikacja jest blokowana przez reguły zapory sieciowej, czy Twoja aplikacja jest dostępna online czy offline? Najłatwiejszym sposobem sprawdzenia * jest * pewien rodzaj pingowania. – robertc

+0

@robertc Twój komentarz ma dla mnie wiele sensu, dzięki! –

Odpowiedz

13

Prostym sposobem sprawdzenia jest dodanie sekcji rezerwowej w swoim manifeście tak:

FALLBACK 
/online.js /offline.js 

Następnie w online.js ustawić zmienną globalną wartość true, w offline.js go ustawić na false i po prostu żądasz online.js przez Ajax za każdym razem, gdy planujesz zrobić coś w sieci i zrobić wszystko, co potrzebujesz warunkowo w wywołaniu zwrotnym. Tymczasem zachowaj wszystkie dane klienta aplikacji.

Alternatywnym podejściem jest a blocking polyfill for navigator.onLine as suggested by Remy Sharp.

+0

Wygląda na całkiem solidne rozwiązanie! –

+0

działa jak urok! –

0

Co powiesz na wykonanie obsługi błędów. Jak pętla Try Catch.

try { 
    //Run some code here 
    } 
catch(err) { 
    //Handle errors here 
    } 
+0

hmm, jaki kod zamierzasz tam uruchomić? –

+1

zrobić coś jak nawigować do Google.com, a następnie ustawić wartość logiczną jako prawdą, jeśli działa lub fałsz, jeśli nie. Istnieje bardzo duża szansa, że ​​Google nie zawiedzie ... nigdy. Masz więc większą szansę na sprawdzenie, czy aplikacja działa w trybie online, a nie tylko to, że zasób sieciowy, do którego próbujesz uzyskać dostęp, jest offline. –

+1

Dostępność Google i tryb offline dla mojej aplikacji - to ogromna różnica. Jak już powiedziałem w moim pytaniu, po prostu zatrzymuję lokalny serwis internetowy. Nie "zatrzymuję" internetu. –

3

stan on-line może być również sprawdzone robi ajax HEAD wniosek o przerwę i po osiągnięciu limitu czasu (lub wywołanie zwraca kod błędu) można założyć, że pracujesz w trybie offline (bez capabitlities sieciowych) i cię zamiast tego trzeba użyć localstorage.

W rzeczywistości, ze względu na spójność państwa, localstorage powinno być używane jako zabezpieczenie nie tylko w trybie offline, ale także w trybie online, a konkretny zasób ajax jest tymczasowo niedostępny (np. przeciążenie witryny). Oczywiście będziesz musiał dokonywać ciągłego odpytywania do tego zasobu z regularnym (lub przyrostowym) przekroczeniem czasu, dopóki nie stanie się ponownie dostępny.

0

Czy jest opcja, aby zapytać localstorage, gdy wywołanie ajax nie powiedzie się z określonym błędem (limit czasu operacji)?

Lub ponieważ strona (przynajmniej częściowo) jest generowana za pomocą skryptu serwera, można dołączyć znacznik czasu żądania (lub unikalny identyfikator) na stronie ze skryptem po stronie serwera i umieścić go w localstorage. Następnie możesz sprawdzić, czy strona jest ładowana z pamięci podręcznej, sprawdzając zapisany identyfikator względem wyrenderowanego.

0

Najlepszą opcją może być użycie zdarzenia error funkcji jQuery $.get() w celu wysłania zapytania do localStorage zamiast do serwera WWW. Ma to tę zaletę, że cofa się, jeśli serwer stanie się nieosiągalny, a także jeśli cały internet użytkownika będzie nieosiągalny.

$.get({ 
    success: //deal with postback from ajax call, 
    error: //Whoops no access to server deal with it in a local way 
}) 
1

ja potrzebuje takiej samej funkcjonalności i po wielu poszukiwaniach znaleziono tę funkcję:

http://louisremi.com/2011/04/22/navigator-online-alternative-serverreachable/

Oto kod z artykułu, na wszelki wypadek link idzie w dół:

function serverReachable() { 
    // IE vs. standard XHR creation 
    var x = new (window.ActiveXObject || XMLHttpRequest)("Microsoft.XMLHTTP"), 
    s; 
    x.open(
     // requesting the headers is faster, and just enough 
     "HEAD", 
     // append a random string to the current hostname, 
     // to make sure we're not hitting the cache 
     window.location.href.split("?")[0] + "?" + Math.random(), 
     // make a synchronous request 
     false 
); 
    try { 
     x.send(); 
     s = x.status; 
     // Make sure the server is reachable 
     return (s >= 200 && s < 300 || s === 304); 
    } 
    // catch network & other problems 
    catch (e) { 
    return false; 
    } 
} 

Zauważ, że powyższy kod zawiera poprawkę Scott'a Jehl'a do pracy z localhostem, który jest umieszczany niżej w komentarzach. A tu jest link do wersji jQuery o tej samej funkcji:

https://gist.github.com/scottjehl/947084

i kod z tego linku:

function serverReachable() { 
    var s = $.ajax({ 
      type: "HEAD", 
      url: window.location.href.split("?")[0] + "?" + Math.random(), 
      async: false 
     }).status; 
    return s >= 200 && s < 300 || s === 304; 
}; 

Znalazłem to technika być naprawdę skuteczne. Ponieważ żądanie dotyczy tylko informacji w nagłówku, jest dość szybkie i działa we wszystkich przeglądarkach. Wielki sukces! :)

Mam nadzieję, że inni uznają to za pomocne, tak jak ja. :)