I am trying to build a web app for iphone, and I don't understand
how to cache all the files under the "images" directory ?
and I modify one file on the server like "brandDB.txt", how to make the cache manifest update this file, and this file only to avoid downloading everything again ?
Thanks
CACHE MANIFEST
# 20131104-1430
index.html
brandDB.txt
icon.png
splashiphone.png
touch-icon-iphone.png
css/style.css
images/shareicon.png
images/bourez.png
images/john.png
...
NETWORK:
*
FALLBACK:
I did a program to easily generate the cache manifest file with the complete list directly from the Windows explorer, if you need it : http://matthieu.com/cmfg/
how to cache all the files under the "images" directory ?
List them all in the manifest file (easiest to use a script to generate the list if it's a lot of files).
how to make the cache manifest update this file, and this file only to avoid downloading everything again
Ensure your HTTP headers are set correctly for the frequency of updates you expect
Update the manifest file
The browser will populate the app cache from its own cache if you've set the headers on each file to allow caching. If you want to version control the files without using HTTP headers, add a query string to the end of the file, eg. brandDB.txt?v=1 - be sure to update the reference in the application if you do that, however.
Well, What I'm going to say, unfortunately is as Jake Archibald Said:
"Application cache is a douchebag !" (Good Article on how it works (not actually a douchebag))
http://alistapart.com/article/application-cache-is-a-douchebag
Basically, you could create a script to list all your files in your image directory
and paste it inside a generated AppCache File.
Application cache will only update when its file's content is changed , you'll also need ensure that the file itself is not cached.
I think you'll be needing your clients to reload the page twice for them to actually see the updates. (You could however using javascript tell the user that the page has updated and they'll need to refresh)
Related
Here is my manifest :
CACHE MANIFEST
CACHE:
//code.jquery.com/jquery-2.0.3.min.js
NETWORK:
*
My index.html which defines that manifest (<html manifest="app.manifest>) is always stored as "Master" even with the NETWORK wildcard part of my manifest.
The problem is that my MASTER index.html is stored in the cache... and won't be refreshed if it changes on the server side if the manifest file is not updated.
I've seen multiple not really beautiful solutions to that problem (like the iframe solution), so my question is : is there a clean HTML 5 way to do this ?
The clean way to do it is to only have static content in your index.html file then load the data dynamically (eg. via AJAX) to create the page the user sees. An alternative would be to have a big link which says 'Enable Offline Support' which links to a page with the manifest link in it.
Other than that, the iframe solution is the cleanest way - you're hacking around the intended use of AppCache, why do you expect that to be 'clean'? What application scenario do you have that jquery-2.0.3.min.js needs to be available offline but not the index page of the app which accesses it?
The situation:
Made htaccess remove file extension so when I access www.example.com/index.html it will link to www.example.com/index/
Created a cache manifest (works fine so we can rule out problems with its structure)
The problem:
Even since I made htaccess change links, cache manifest no longer works for index.html
example:
CACHE MANIFEST
index.html
and in console I would get cache manifest resource fetch failed (-1).
this is probably because when the browser tries to access www.example.com/index.html it would get redirected to www.example.com/index/ and it is confused?
Is there any way to get it to cache the link directly? Thanks.
Could it be that all files that are to be stored in the cache need to be explicitly stated, or in other words, the full absolute URL has to be written or a full relative URL must be written in order for the cache to download the file.
aka
index.html
blablah.js
hello/world.png
all should work but
index/
bippitybop/js/
goodbye_cruel/world/*
won't work.
Let me know if this helps, if this question is even still active.
It seems that if the cache manifest on the server changes it will re-download everything in file? Is there any way to only make it re-download some of the files? If I only make code fixes to a script and then update the manifest (say just put a timestamp comment in it) to force local copies to see a change has been made, I might not want images re-downloaded that haven't changed but still need to be in the manifest. Is there a way to get more precision around this or is it an all or nothing thing?
From what i've expreienced, updating the cache manifest doesn't explicitly download all the content again, but rather checks if they've been modified. So if there are 10 items in your cache manifest and you were to update a single file (and also the manifest file), then each file would be checked for modification, and depending on how they are being served (CDN?) they should be returning a 304 Not Modified, and thus not be downloaded again.
I have a lot of images in a folder that are used in the application. When using the cache manifest it would be easier maintenance wise if I could specify a wild card to load all the images or files in a certain directory to be cached.
E.g.
CACHE MANIFEST
# 2011-11-3-v0.1.8
#--------------------------------
# Pages
#--------------------------------
../index.html
../edit.html
#--------------------------------
# JavaScript
#--------------------------------
../js/jquery.js
../js/main.js
#--------------------------------
# Images
#--------------------------------
../img/*.png
Can this be done? Have tried it in a few browsers with ../img/* as well but it doesn't seem to work.
It would be easier, but how's it going to work? The manifest file is something which is parsed and acted upon in the browser, which has no special knowledge of files on your server other than what you've told it. If the browser sees this:
../img/*.png
What is the first image the browser should request from the server? Let's start with these:
../img/1.png
../img/2.png
../img/3.png
../img/4.png
...
../img/2147483647.png
That's all the images that might exist with a numeric name, stopping semi-arbitrarily at 231-1. How many of those 2 billion files exist in your img directory? Do you really want a browser making all those requests only to get 2 billion 404s? For completeness the browser would probably also want to request all the zero-filled equivalents:
../img/01.png
../img/02.png
../img/03.png
../img/04.png
...
../img/001.png
../img/002.png
../img/003.png
../img/004.png
...
../img/0001.png
../img/0002.png
../img/0003.png
../img/0004.png
...
Now the browser's made more than 4 billion HTTP requests for files which mostly aren't there, and it's not yet even got on to letters or punctuation in constructing the possible filenames which might exist on the server. This is not a feasible way for the manifest file to work. The server is where the files in the img directory are known, so it's on the server that the list of files has to be constructed.
I don't think it works that way. You'll have to specify all of the images one by one, or have a simple PHP script to loop through the directory and output the file (with the correct text/cache-manifest header of course).
It would be a big security issue if browsers could request folder listings - that's why Tomcat turns that capability off by default now.
But, the browser could locate all matches to the wildcards referenced by the pages it caches. This approach would still be problematic (like, what about images not initially used but set dynamically by JavaScript, etc., and it would require that all cached items not only be downloaded but parsed as well).
If you are trying automate this process, instead of manually doing it. Use a script, or as I do I use manifestR. It will output your manifest/appcache file and all you have to do is copy and paste. I've used it successfully and usually only have to make a few changes.
Also, I recommend using the network header with the wild card:
NETWORK:
*
This allows all assets from other linked domains via JSON, for instance, to download into the cache. I believe that this is the only header where you can specify a wildcard. Like the others have said here, it's for security reasons.
The cache manifest is now deprecated and you should use HTML headers to control caching.
For example:
<meta http-equiv="Cache-control" content="public">
Public - may be cached in public shared caches.
Private - may only be cached in private cache.
No-Cache - may not be cached.
No-Store - may be cached but not archived.
Every URL can be linked to a single cache manifest. But I want several cache manifests linked to a same URL. Here is the reason:
Some files I want to be cached are rarely updated and large.
So everytime the cache gets updated these large files get re-downloaded even though they may not have been changed.
So I want to split up the cache. One cache for theses rarely updated large files and another cache for the often updated light files.
Do you guys have any idea how to split up an HTML5 cache?
The most efficient way is:
a) Use far-future expiration date (max-age) on all resources mentioned in manifest's CACHE section and add timestamp suffix to each file in the CACHE section, e.g.:
CACHE:
menu_1355817388000.js
toolbar_1355817389100.js
b) When any of the above files change on the server, regen/update manifest to change the timestamp. Only the file with the modified timestamp will get downloaded next time. Mission accomplished.
Note: Reload the page twice in the browser, as on the first refresh browser downloads just the manifest and uses old cached resources to paint the page. This is done to speed up displaying the page (there are tricks to handle this issue of double refresh, but they are outside the scope of your question)
See more info in this long but best article I ever seen on appcache.
Use an iframe
Your page's cache manifest would include the light files and the cache manifest of an iframe loaded by this page would include the large files
On chrome the iframe's application cache will also be used for the page. I didn't tested this method on other browsers yet.
see a live example at http://www.timer-tab.com and if you are using chrome see its split up cache at chrome://appcache-internals/
When the manifest file is changed and the files of the application cache are downloaded again, the normal HTTP caching rules still apply. This means that if you set the correct HTTP caching headers for these large files, you'll get a 304 so these files are not downloaded again. So it's not necessary to split the application cache.
Maybe an answer but I'd more like to shed some light on my findings as a I troubleshoot my own webapp.
I've discovered that I can use 2 iframes (manifest_framework) and (manifest_media) to load the manifests, but i'm still not exactly clear how they are targetted, but I had limited success.
manifest_framework:
CACHE MANIFEST
CACHE:
appdata.ini
dialog.png
jquery.min.js
login.htm
login.js
manifest.appcache.js
NETWORK:
*
FALLBACK:
manifest_media:
CACHE MANIFEST
CACHE:
manifest_fwk.php
od/audio_track_1_1.m4a
od/audio_track_1_2.m4a
od/audio_track_1_3.m4a
od/audio_track_1_4.m4a
od/video_1.mp4
od/video_2.mp4
od/video_3.mp4
NETWORK:
*
FALLBACK:
./ webapp.php
./index.php is the page the 'landing page' which itself isn't cached but falls back to webapp.php when offline.
What I don't understand is how these link to the webapp.php page.
I am finding I can only get access to one or the other manifests cache.
The above works in mobile safari, the media would be cached, and image but not necessarily the JS or images in the framework manifest.
Anyone have more examples where multiple manifests are referenced from the one URL/page?
The W3C working group has abandoned the file system api, so it SHOULD NOT BE USED anymore.
We'll likely see it fall off the next version of Chrome.
http://www.w3.org/TR/file-system-api/
CACHE MANIFEST
# This is a comment.
# Cache manifest version 0.0.1
# If you change the version number in this comment,
# the cache manifest is no longer byte-for-byte
# identical.
demoimages/mypic.jpg
demoimages/yourpic.jpg
demoimages/ourpic.jpg
sr/scroll.js
NETWORK:
# All URLs that start with the following lines
# are whitelisted.
# whitelisted items are needed to help the site function, you could put regularly
# changing items here
http://example.com/examplepath/
http://www.example.org/otherexamplepath/
CACHE:
# Additional items to cache.
demoimages/allpics.jpg
FALLBACK:
demoimages/currentImg.jpg images/stockImage.jpg`
If the Iframe trick does not work, use the HTML5 FileSystem API
See http://updates.html5rocks.com/2012/04/Taking-an-Entire-Page-Offline-using-the-HTML5-FileSystem-API