2009-11-11 12 views
52

Aktualnie używam Manifestu pamięci podręcznej (zgodnie z opisem here). Dzięki temu zasoby są niezbędne do uruchomienia aplikacji, gdy użytkownik jest offline.Jak prawidłowo unieważnić Manifest w pamięci podręcznej HTML5 dla internetowych aplikacji internetowych?

Niestety, działa zbyt dobrze.

Po załadowaniu manifestu pamięci podręcznej, Firefox 3.5+ buforuje wszystkie zasoby jawnie wymienione w manifeście pamięci podręcznej. Jeśli jednak plik na serwerze zostanie zaktualizowany, a użytkownik spróbuje odświeżyć stronę w trybie online (w tym sam manifest pliku podręcznego), Firefox absolutnie nie będzie niczego pobierał. Aplikacja pozostaje całkowicie zamrożona w ostatnim punkcie, w którym była przechowywana w pamięci podręcznej. Pytania:

  1. Chcę, aby Firefox skutecznie polegał na buforowanych zasobach, gdy połączenie sieciowe zawiedzie. Próbowałem użyć bloku FALLBACK, ale bezskutecznie. Czy to możliwe?
  2. Jeśli # 1 nie jest możliwe, czy użytkownik może wymusić odświeżenie strony i pominąć pamięć podręczną (ctrl-F5 tego nie robi, a także czyszczenie pamięci podręcznej przeglądarki, szokująco) nie powoduje wyczyszczenia ich prywatnych dane? Alternatywnie, czy mechanizm manifestu pamięci podręcznej obsługuje nagłówki wygaśnięcia i czy jego zachowanie w odniesieniu do tego jest udokumentowane w dowolnym miejscu?
+1

Widziałem ten przykładowy problem występujący z przerwami. Zwykle aktualizowanie pliku w manifeście, a następnie aktualizowanie numeru wersji komentarza w manifeście powoduje przeładowanie zaktualizowanego pliku, ale czasami Firefox blokuje się i odmawia przeładowania nowego zasobu, mimo że nic nie jest nie tak z manifestem. Jedynym sposobem rozwiązania problemu jest wyczyszczenie pamięci podręcznej trybu offline, ale nie jest to dopuszczalne w przypadku aktualizacji wdrażania. – Michael

Odpowiedz

25

Myślę, że mam to zorientowali się: jeśli istnieje błąd w jednym manifestu pamięci podręcznej (np. Plik odniesienia nie istnieje), a następnie Firefox całkowicie przestanie przetwarzać coś związanego z appCache. Oznacza to, że nie zaktualizuje niczego w pamięci podręcznej, w tym w buforze podręcznym manifestu.

Aby odkryć, że to był problem, I borrowed some code from Mozilla i upuściłem to do nowego (niezbuforowanego) pliku HTML w mojej aplikacji. Ostatnia zarejestrowana wiadomość oświadczyła, że ​​może występować problem w moim pliku manifestu pamięci podręcznej i na pewno istnieje (brakujący plik).


// Convenience array of status values 
var cacheStatusValues = []; 
cacheStatusValues[0] = 'uncached'; 
cacheStatusValues[1] = 'idle'; 
cacheStatusValues[2] = 'checking'; 
cacheStatusValues[3] = 'downloading'; 
cacheStatusValues[4] = 'updateready'; 
cacheStatusValues[5] = 'obsolete'; 

// Listeners for all possible events 
var cache = window.applicationCache; 
cache.addEventListener('cached', logEvent, false); 
cache.addEventListener('checking', logEvent, false); 
cache.addEventListener('downloading', logEvent, false); 
cache.addEventListener('error', logEvent, false); 
cache.addEventListener('noupdate', logEvent, false); 
cache.addEventListener('obsolete', logEvent, false); 
cache.addEventListener('progress', logEvent, false); 
cache.addEventListener('updateready', logEvent, false); 

// Log every event to the console 
function logEvent(e) { 
    var online, status, type, message; 
    online = (isOnline()) ? 'yes' : 'no'; 
    status = cacheStatusValues[cache.status]; 
    type = e.type; 
    message = 'online: ' + online; 
    message+= ', event: ' + type; 
    message+= ', status: ' + status; 
    if (type == 'error' && navigator.onLine) { 
     message+= ' There was an unknown error, check your Cache Manifest.'; 
    } 
    log('
'+message); } function log(s) { alert(s); } function isOnline() { return navigator.onLine; } if (!$('html').attr('manifest')) { log('No Cache Manifest listed on the tag.') } // Swap in newly download files when update is ready cache.addEventListener('updateready', function(e){ // Don't perform "swap" if this is the first cache if (cacheStatusValues[cache.status] != 'idle') { cache.swapCache(); log('Swapped/updated the Cache Manifest.'); } } , false); // These two functions check for updates to the manifest file function checkForUpdates(){ cache.update(); } function autoCheckForUpdates(){ setInterval(function(){cache.update()}, 10000); } return { isOnline: isOnline, checkForUpdates: checkForUpdates, autoCheckForUpdates: autoCheckForUpdates }

To był na pewno pomocne, ale należy zdecydowanie zażądać funkcji z Mozilli, który drukuje się zniekształcone Cache-manifesty przynajmniej do konsoli błędów. Nie należy wymagać niestandardowego kodu dołączanego do tych zdarzeń, aby zdiagnozować problem tak trywialny jak plik o zmienionej nazwie.

+2

Możesz użyć skryptozakładki [Manifesto] (http://manifesto.ericdelabar.com) do sprawdzenia poprawności manifestu pamięci podręcznej. – Maarten

7

Nota prawna: moje wrażenia z manifestów i pamięci podręcznej to wszystko Safari i FF mogą obsługiwać niektóre rzeczy inaczej.

  1. Masz całkowitą rację. Jeśli na manifeście znajdują się jakieś pliki, których nie można znaleźć, nie nastąpi buforowanie.

  2. Nawet jeśli jesteś online, przeglądarka sprawdzi tylko plik manifestu. Podczas oczekiwania na plik manifestu będzie nadal ładował witrynę z pamięci podręcznej - w ten sposób nie opóźnia renderowania - ale oznacza to, że nie widać żadnych zmian przy pierwszym ładowaniu.

  3. Przy następnym załadowaniu strony, jeśli manifest został zmieniony przy poprzednim załadowaniu, nowe pliki zostaną załadowane.

ZAWSZE ZWRACAĆ SIĘ DO DWÓCH KONIECZNOŚCI, aby zobaczyć jakiekolwiek zmiany. W rzeczywistości czasami musiałem przeładować 3 razy, aby zobaczyć aktualizację. Nie mam pojęcia dlaczego.

Podczas debugowania generuję plik manifestu w locie za pomocą php, więc nie ma szans na literówkę w nazwie pliku.Generuję również numer wersji losowo za każdym razem, aby wymusić aktualizację, ale nadal mam aplikację internetową do testowania offline.

Po zakończeniu, plik php może po prostu wyświetlać zapisane dane manifestu ze stałym numerem wersji, a pamięć podręczna zawsze będzie używana.

Kilka rzeczy, których się nauczyłem podczas gry z manifestem i pamięcią podręczną ostatnio. Działa świetnie, ale może być mylące.

Nie ma terminu wygaśnięcia. Aby wykonać uncache, musisz zmienić plik manifestu, aby nie zawierał niczego i przeładować. W Safari wyczyszczenie pamięci podręcznej użytkownika usuwa wszystkie zbuforowane pliki.

+0

Prawie dokładnie odzwierciedla moje doświadczenie w FireFox, z wyjątkiem faktu, że czyszczenie pamięci podręcznej użytkownika w Safari najwyraźniej czyści pamięć podręczną HTML. Dzięki za wkład. –

+0

Mam bardzo podobne doświadczenia z nadmiernym buforowaniem i odmową wyczyszczenia pamięci podręcznej. Sporo razy w Safari (zarówno na komputerze, jak i na urządzeniach mobilnych) musiałem otworzyć nową kartę w przeglądarce (na pulpicie) lub zrestartować urządzenie (na iPadzie), aby wymusić ponowne załadowanie, gdy zostanie zablokowane "z jakiegoś niezrozumiałego powodu. Uważam, że zatrzymanie wszystkich aktualizacji jest bardzo użyteczne dla zidentyfikowania tego (np. Kiedy zaczyna sprawdzać aktualizację, ale nigdy nie uruchamia zdarzenia "aktualizacja zakończona", "postęp" lub "błąd", od razu wiem, że to problem z klientem, a nie Aplikacja). –

+0

O, i interesująca rzecz w Firefoksie (być może innych przeglądarkach) - zmiana zakomentowanej linii w manifeście (podejście zalecane przez dokumentację deweloperską Apple'a) NIE powoduje wywołania aktualizacji pamięci podręcznej. * Musisz * dodać lub usunąć wiersz z aktywną instrukcją (np. Faktycznie dodać lub usunąć wpis dla pliku z manifestu pamięci podręcznej), zanim uzna, że ​​manifest został zaktualizowany. –

2

Hmm, właśnie wywołałem update() na pamięci podręcznej, po wprowadzeniu zmiany w pliku manifestu i otrzymałem pełną sekwencję sprawdzania/pobierania/gotowości, wykonałem jedno przeładowanie i zmianę tekstu, którą wprowadziłem jeden z moich plików js, który pojawia się na początkowej stronie mojej aplikacji, natychmiast się pojawił.

Wygląda na to, że potrzebuję tylko jednego przeładowania.

3

Zrobiłem dodatek Firefox, który unieważnił Manifest pamięci podręcznej i wyczyści HTML5 Local Storage.

http://sites.google.com/site/keigoattic/home/webrelated#TOC-Firefox-HTML5-Offline-Cache-and-Loc

Można również unieważnić cache oczywistego wpisując poniższy kod w konsoli błąd:

// invalidates the cache manifest 
var mani = "http://.../mysite.manifest"; // manifest URL 
Components.classes["@mozilla.org/network/application-cache-service;1"].getService(Components.interfaces.nsIApplicationCacheService).getActiveCache(mani).discard(); 

Albo wpisując poniższy kod w pasku adresu będzie ręcznie enforece cache do zostać zaktualizowany:

javascript:applicationCache.update() 
+0

Dziękujemy! Twoja wtyczka jest trochę trudna do zainstalowania, ale działa cudownie! –

+0

Dziękujemy! pisząc, że w konsoli Firebug w about: config podstęp! –

+0

Czy możesz użyć tej linii w javascriptie pliku, aby pamięć podręczna aktualizowała się, gdy użytkownik jest w trybie online, ale oczywiście nie będzie działał w trybie offline? lub czy linia złamie kod w trybie offline? – trgraglia

15

Użyłem kodu z HTML5 Rocks: Update the cache:

window.addEventListener('load', function(e) { 
    if (window.applicationCache) { 
    window.applicationCache.addEventListener('updateready', function(e) { 
     if (window.applicationCache.status == window.applicationCache.UPDATEREADY) { 
      // Browser downloaded a new app cache. 
      // Swap it in and reload the page to get the new hotness. 
      window.applicationCache.swapCache(); 
      if (confirm('A new version of this site is available. Load it?')) { 
      window.location.reload(); 
      } 
     } else { 
      // Manifest didn't changed. Nothing new to server. 
     } 
    }, false); 
    } 
}, false); 
+1

To wydaje się wymagać zmiany w manifeście. Sam aktualizacja pliku nie spowoduje aktualizacji. – trgraglia

+0

Dzięki, to jedyny sposób, w jaki znalazłem aktualizację aplikacji, jeśli buforujesz główny index.html – evilcelery

+0

Polecam użyć window.location.reload (true), ponieważ dokumenty określają "true - ładuj zawartość z serwera " – JakubKnejzlik

7

Miałem ten sam problem: po tym, jak Firefox zapisał pliki trybu offline, nie przeładowałoby ich nigdy. Chrome działał zgodnie z oczekiwaniami, sprawdził plik manifestu pod kątem zmian i ponownie załadował wszystko, gdy plik manifestu się zmienił. Firefox nawet nie pobrał pliku manifestu z serwera, więc nie mógł zauważyć zmian.

Po przeprowadzeniu dochodzenia dowiedziałem się, że Firefox buforował plik manifestu pamięci podręcznej (staroświecka pamięć podręczna, a nie pamięć podręczna trybu offline). Ustawienie nagłówka pamięci podręcznej pliku manifestu na Cache-Control: no-cache, private rozwiązało problem.

+0

@brianl Wycofałem zatwierdzoną przez Ciebie edycję. Meta tagi nie mają tu zastosowania, ponieważ manifest cache nie jest plikiem html. – OlliM

Powiązane problemy