HTML5 Rocks A Beginner's Guide To Using The Application Cache
User Manual:
Open the PDF directly: View PDF
.
Page Count: 10

HTML ROCKS
SlidesPlaygroundStudioTutorialsResources
EricBidelmanDeveloperRelations,Google
June18,2010 (updated:May27,2011)
34
26Tosemilíbí
1
14Commentsand0Reactions
Supportedbrowsers:
Home>Tutorials>ABeginner'sGuidetoUsingtheApplicationCache
A Beginner's Guide to Using the Application
Cache
Yourbrowserappearstosupportallofthefunctionalityusedinthisarticle.
Introduction
Thecachemanifestfile
Referencingamanifestfile
Structureofamanifestfile
Updatingthecache
Cachestatus
AppCacheevents
References
Introduction
It'sbecomingincreasinglyimportantforwebbasedapplicationstobeaccessibleoffline.Yes,all
browsershavecachingmechanisms,butthey'reunreliableanddon'talwaysworkasyoumight
expect.HTML5addressessomeoftheannoyancesofbeingofflinewiththeApplicationCache
interface.
Usingthecacheinterfacegivesyourapplicationthreeadvantages:
1. Offlinebrowsinguserscannavigateyourfullsitewhenthey'reoffline
2. Speedcachedresourcesarelocal,andthereforeloadfaster.
3. Reducedserverloadthebrowserwillonlydownloadresourcesfromtheserverthathave
changed.
TheApplicationCache(orAppCache)allowsadevelopertospecifywhichfilesthebrowsershould
cacheandmakeavailabletoofflineusers.Yourappwillloadandworkcorrectly,eveniftheuser
pressestherefreshbuttonwhilethey'reoffline.
The cache manifest file
Thecachemanifestfileisasimpletextfilethatliststheresourcesthebrowsershouldcachefor
offlineaccess.
Referencing a manifest file
SearchHTML5Rocks

Toenabletheapplicationcacheforanapp,includethemanifestattributeonthedocument'shtml
tag:
<htmlmanifest="example.appcache">
...
</html>
Themanifestattributeshouldbeincludedoneverypageofyourwebapplicationthatyouwant
cached.Thebrowserdoesnotcacheapageifitdoesnotcontainthemanifestattribute(unless
itisexplicitlylistedinthemanifestfileitself.Thismeansthatanypagetheusernavigatestothat
includeamanifestwillbeimplicitlyaddedtotheapplicationcache.Thus,there'snoneedtolist
everypageinyourmanifest.
ThemanifestattributecanpointtoanabsoluteURLorrelativepath,butanabsoluteURLmust
beunderthesameoriginasthewebapplication.Amanifestfilecanhaveanyfileextension,but
needstobeservedwiththecorrectmimetype(seebelow).
<htmlmanifest="http://www.example.com/example.mf">
...
</html>
Amanifestfilemustbeservedwiththemimetypetext/cachemanifest.Youmayneedtoadd
acustomfiletypetoyourwebserveror.htaccessconfiguration.
Forexample,toservethismimetypeinApache,addthislinetoyourconfigfile:
AddTypetext/cachemanifest.appcache
Or,inyourapp.yamlfileinGoogleAppEngine:
url:/mystaticdir/(.*\.appcache)
static_files:mystaticdir/\1
mime_type:text/cachemanifest
upload:mystaticdir/(.*\.appcache)
Structure of a manifest file
Asimplemanifestmaylooksomethinglikethis:
CACHEMANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
Thisexamplewillcachefourfilesonthepagethatspecifiesthismanifestfile.
Thereareacoupleofthingstonote:
TheCACHEMANIFESTstringisthefirstlineandisrequired.
Sitesarelimitedto5MBworthofcacheddata.However,ifyouarewritinganappforthe
ChromeWebStore ,usingtheunlimitedStorageremovesthatrestriction.
Ifthemanifestfileoraresourcespecifiedinitfailstodownload,theentirecacheupdate
processfails.Thebrowserwillkeepusingtheoldapplicationcacheintheeventoffailure.

Letstakealookatamorecomplexexample:
CACHEMANIFEST
#20100618:v2
#Explicitlycached'masterentries'.
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js
#Resourcesthatrequiretheusertobeonline.
NETWORK:
login.php
/myapi
http://api.twitter.com
#static.htmlwillbeservedifmain.pyisinaccessible
#offline.jpgwillbeservedinplaceofallimagesinimages/large/
#offline.htmlwillbeservedinplaceofallother.htmlfiles
FALLBACK:
/main.py/static.html
images/large/images/offline.jpg
*.html/offline.html
Linesstartingwitha'#'arecommentlines,butcanalsoserveanotherpurpose.Anapplication's
cacheisonlyupdatedwhenitsmanifestfilechanges.Soforexample,ifyoueditanimage
resourceorchangeajavascriptfunction,thosechangeswillnotberecached.Youmustmodify
themanifestfileitselftoinformthebrowsertorefreshcachedfiles.Creatingacommentline
withageneratedversionnumber,hashofyourfiles,ortimestampisonewaytoensureusers
havethelatestversionofyoursoftware.Youcanalsoprogrammaticallyupdatethecacheoncea
newversionisreadyasdiscussedintheUpdatingthecachesection.
Amanifestcanhavethreedistinctsections:CACHE,NETWORK,andFALLBACK.
CACHE:
Thisisthedefaultsectionforentries.Fileslistedunderthisheader(orimmediatelyafterthe
CACHEMANIFEST)willbeexplicitlycachedafterthey'redownloadedforthefirsttime.
NETWORK:
Fileslistedunderthissectionarewhitelistedresourcesthatrequireaconnectiontotheserver.
Allrequeststotheseresourcesbypassthecache,eveniftheuserisoffline.Wildcardsmaybe
used.
FALLBACK:
Anoptionalsectionspecifyingfallbackpagesifaresourceisinaccessible.ThefirstURIisthe
resource,thesecondisthefallback.BothURIsmustberelativeandfromthesameoriginas
themanifestfile.Wildcardsmaybeused.
Note:Thesesectionscanbelistedinanyorderandeachsectioncanappearmorethanoneina
singlemanifest.
Thefollowingmanifestdefinesa"catchall"page(offline.html)thatwillbedisplayedwhentheuser
triestoaccesstherootofthesitewhileoffline.Italsodeclaresthatallotherresources(e.g.those
onremoteasite)requireaninternetconnection.
CACHEMANIFEST
#20100618:v3

#Explicitlycachedentries
index.html
css/style.css
#offline.htmlwillbedisplayediftheuserisoffline
FALLBACK:
//offline.html
#Allotherresources(e.g.sites)requiretheusertobeonline.
NETWORK:
*
#Additionalresourcestocache
CACHE:
images/logo1.png
images/logo2.png
images/logo3.png
Note:TheHTMLfilethatreferencesyourmanifestfileisautomaticallycached.There'snoneedto
includeitinyourmanifest,howeveritisencouragedtodoso.
Note:HTTPcacheheadersandthecachingrestrictionsimposedonpagesservedoverSSLare
overriddenbycachemanifests.Thus,pagesservedoverhttpscanbemadetoworkoffline.
Updating the cache
Onceanapplicationisofflineitremainscacheduntiloneofthefollowinghappens:
1. Theuserclearstheirbrowser'sdatastorageforyoursite.
2. Themanifestfileismodified.Note:updatingafilelistedinthemanifestdoesn'tmeanthe
browserwillrecachethatresource.Themanifestfileitselfmustbealternated.
3. Theappcacheisprogramaticallyupdated.
Cache status
Thewindow.applicationCacheobjectisyourprogrammaticaccessthebrowser'sappcache.
Itsstatuspropertyisusefulforcheckingthecurrentstateofthecache:
varappCache=window.applicationCache;
switch(appCache.status){
caseappCache.UNCACHED://UNCACHED==0
return'UNCACHED';
break;
caseappCache.IDLE://IDLE==1
return'IDLE';
break;
caseappCache.CHECKING://CHECKING==2
return'CHECKING';
break;
caseappCache.DOWNLOADING://DOWNLOADING==3
return'DOWNLOADING';
break;
caseappCache.UPDATEREADY://UPDATEREADY==4
return'UPDATEREADY';

break;
caseappCache.OBSOLETE://OBSOLETE==5
return'OBSOLETE';
break;
default:
return'UKNOWNCACHESTATUS';
break;
};
Toprogrammaticallyupdatethecache,firstcallapplicationCache.update().Thiswillattempt
toupdatetheuser'scache(whichrequiresthemanifestfiletohavechanged).Finally,whenthe
applicationCache.statusisinitsUPDATEREADYstate,calling
applicationCache.swapCache()willswaptheoldcacheforthenewone.
varappCache=window.applicationCache;
appCache.update();//Attempttoupdatetheuser'scache.
...
if(appCache.status==window.applicationCache.UPDATEREADY){
appCache.swapCache();//Thefetchwassuccessful,swapinthenewcache.
}
Note:Usingupdate()andswapCache()likethisdoesnotservetheupdatedresourcestousers.
Thisflowsimplytellsthebrowsertocheckforanewmanifest,downloadtheupdatedcontentit
specifies,andrepopulatetheappcache.Thus,ittakestwopagereloadstoservernewcontentto
users,onetopulldownanewappcache,andanothertorefreshthepagecontent.
Thegoodnews:youcanavoidthisdoublereloadheadache.Toupdateuserstothenewest
versionofyoursite,setalistenertomonitortheupdatereadyeventonpageload:
//Checkifanewcacheisavailableonpageload.
window.addEventListener('load',function(e){
window.applicationCache.addEventListener('updateready',function(e){
if(window.applicationCache.status==window.applicationCache.UPDATEREADY){
//Browserdownloadedanewappcache.
//Swapitinandreloadthepagetogetthenewhotness.
window.applicationCache.swapCache();
if(confirm('Anewversionofthissiteisavailable.Loadit?')){
window.location.reload();
}
}else{
//Manifestdidn'tchanged.Nothingnewtoserver.
}
},false);
},false);
AppCache events
Asyoumayexpect,additionaleventsareexposedtomonitorthecache'sstate.Thebrowserfires
eventsforthingslikedownloadprogress,updatingtheappcache,anderrorconditions.The
followingsnippetsetsupeventlistenersforeachtypeofcacheevent:

Like
functionhandleCacheEvent(e){
//...
}
functionhandleCacheError(e){
alert('Error:Cachefailedtoupdate!');
};
//Firedafterthefirstcacheofthemanifest.
appCache.addEventListener('cached',handleCacheEvent,false);
//Checkingforanupdate.Alwaysthefirsteventfiredinthesequence.
appCache.addEventListener('checking',handleCacheEvent,false);
//Anupdatewasfound.Thebrowserisfetchingresources.
appCache.addEventListener('downloading',handleCacheEvent,false);
//Themanifestreturns404or410,thedownloadfailed,
//orthemanifestchangedwhilethedownloadwasinprogress.
appCache.addEventListener('error',handleCacheError,false);
//Firedafterthefirstdownloadofthemanifest.
appCache.addEventListener('noupdate',handleCacheEvent,false);
//Firedifthemanifestfilereturnsa404or410.
//Thisresultsintheapplicationcachebeingdeleted.
appCache.addEventListener('obsolete',handleCacheEvent,false);
//Firedforeachresourcelistedinthemanifestasitisbeingfetched.
appCache.addEventListener('progress',handleCacheEvent,false);
//Firedwhenthemanifestresourceshavebeennewlyredownloaded.
appCache.addEventListener('updateready',handleCacheEvent,false);
Ifthemanifestfileoraresourcespecifiedinitfailstodownload,theentireupdatefails.The
browserwillcontinuetousetheoldapplicationcacheintheeventofsuchafailure.
References
ApplicationCache APIspecification
Exceptasotherwisenoted,thecontentofthispageislicensedundertheCreativeCommonsAttribution3.0License,
andcodesamplesarelicensedundertheApache2.0License.
14peoplelikedthis.
LoginAdd New Comment

Sortbypopularnow
Showing 14 comments
Whatcanbedonetocacheeverythingexceptthepagethatiscallingthefile.Ihavea
dynamicapp,IwanttocacheallthesupportingCSS,images,etc,butIdon'twantthe
actualpagestobecached.WilllistingthepagesintheNETWORKsectionbeenoughto
overridetheautomaticinclusionoffilesthatcallthecache?
NicholasCardot
Like
Reply
3monthsago
1Like
youcanworkaroundthiswithaniframe,http://saikotroid.blogspot.com...
Viktor
Like
Reply
2monthsago
inreplytoNicholasCardot
Isthereanythingpossibleforconditionalcaching?
[EDIT]
IhaveremovedmyquestionbecauseIEdoesnotsupporthtml5caching
solsTiCed'Hiver
Like
Reply
3weeksago
foralargewebsite,canthewebserverautomaticallyupdateandversionthemanifestfileif
itdetectschangestofiles,orshouldthisbehandledbyasiteadmin/script?
Rich
Like
Reply
1monthago
Sure.Checkthisdymanicmanifestout:https://github.com/ebidel/html...
Itchangesthe"versioncommentstring"onlywhenoneofthemanifest'sfilecontent
changes.
That'sdownbycheckinganmd5ofallofthefiles'content.
EricBidelman
Like
Reply
1monthago
inreplytoRich
TheAddTypeConfigurationsaretobedoneinthehttpd.conffileifyouareusingApache
WebServer.
Jaydeep

Like
Reply
1monthago
Cachingthepagewhichcontainsthemanifest.appcachefileisnotrecommended.Keeping
suchapageinNETWORK:partofmanifest.appcachehelpsinupdationoftheApplicaiton
Cacheeverytimethewebsiteisbrowsed.
Jaydeep
Like
Reply
1monthago
PuttingthemasterentryintheNETWORK:sectionwon'twork.Thepagethat
referencesthemainfestfile(themasterentry)isalwayscached.There'snoway
aroundthat.
EricBidelman
Like
Reply
1monthago
inreplytoJaydeep
I'malittlelatetothisparty,buthopefullysomeoneherecanhelp.InSafari/Chromethe
appcacheworksformeasexpected.InFF(5.0.1)thecacheredownloadsoneverypage
visit...asthoughthemanifesthasbeenchanged.Anyoneelseseethisorhaveanyinsight?
Brian
Like
Reply
2monthsago
UPDATEREADY==5
shouldbeUPDATEREADY==4
DCam
Like
Reply
4monthsago
Goodcatch.I'llmakethefix.Thanks!
EricBidelman
Like
Reply
4monthsago
inreplytoDCam
HereisatipwhenbuildinganHTML5webappusingCacheManifest.IfyouareusingPHP
oranotherdynamicscriptinglanguageistouseaGETvariabletofilterouttheCache
Manifest.
Iamcurrentlybuildingawebappandwanttotestitoutinbothacachedandnoncached
state.Insteadofhavingtwoseparateinstances,IuseaGETvariabletofilteroutthe
MacHarborGuy

Cacheattribute.
OnmyiPhoneIhavetwoHomeScreenbookmarks,oneleadingtotheURLandanother
withaGETvariablewithsomehardtoguessstring.IftheGETvariableexists,thecache
attributeisneveraddedtothedocument,andneverforcesthebrowsertocachethesite.If
itdoesnotexist,thesiteiscached.
ThenicepartaboutthewaytheiPhonehandlesHomeScreenWebAppbookmarksis
that...
http://www.example.com
and...
http://www.example.com/?var=1
aretreatedasseparateinstanceswhentheCacheisconcerned.
Thisallowsmeto,aslongasIdon'tmodifythecache.manifestfile,havealivecached
versionoftheappfortesting,andanoncachedversiontoquicklypreviewchanges
withouthavingtoeventouchthemanifest(whichcanbeveryobtrusiveduringtheinitial
development).
WhatisevenbetteristheabilitytowhitelistremoteserverURLs(theGoogledomains,for
example,withtheGoogleMapsJavascriptAPI)intheNETWORK:section.Justmakesure
yougetalloftheremoteURLswhitelisted,otherwiseyouwillhaveanappthatdoesn't
work.SofarIhave6GoogleURLswhitelisted.Iamguessingtherearemore,butatthis
pointIhavenotrunintothem.
Like
Reply
6monthsago
"Theseentries(i.e.everythingunderaCACHEheading)mustfollowthesameorigin
policy"
Areyousure?Cachingascriptfromadifferentdomainseemstoworkforme...
LouisRémiBabé
Like
Reply
6monthsago
You'rerightLouis.TheCACHEentriescanbefromadifferentorigin.It'sthe
manifestattributeonthatmustbefromthesameorigin.I'llupdatethosesections.
Thanks!
EricBidelman
Like
Reply
6monthsago
inreplytoLouisRémiBabé
3Likes

MSubscribebyemail SRSS
TrackbackURL
http://disqus.com/forums/html5rocks/html5_rocks_a_beginners_guide_to_using_the_application_cache/trackback/
MadebyGoogle|
TermsPrivacyReportbugorrequestafeatureFollowusonTwitterAboutAuthors
ThissitecontainsinformationonAPIsthatarenotpartoftheW3CHTML5
specification.