HTML5 Cache fallback - html

I am experimenting with HTML5 caching and i have stumbled onto a problem.
CACHE MANIFEST
/Default.aspx
/Offline.aspx
/js/jquery-1.6.4.min.js
/js/jquery.mobile-1.0rc2.min.js
/css/jquery.mobile-1.0rc2.min.css
/css/images/ajax-loader.png
/css/images/icons-18-white.png
FALLBACK:
/ Offline.aspx
NETWORK:
*
So my starting page is Default.aspx, when the device goes offline it should redirect to /Offline.aspx but it doesn't. Now all i can figure is because /Default.aspx is cached.
Now let's say i remove /Default.aspx from the manifest, It would still be cached because it's referencing the manifest in the HTML tag.
I have read dozens of pages concerning html caching but i can't find an answer.
Any advice would be great!
Thanks

Yes, this is the behavior that you should expect because if the page that references the manifest is not declared in the manifest itself (explicit), it will be considered part of the manifest implicitly as a "master" page - and from that point forward will be cached and not updated until the manifest changes.
This was not entirely clear to me either until I experienced that same behavior (in the application that I was adding offline capabilities to) and dug into the spec to better understand the observed behavior.
My solution to this was to turn the dynamic parts of that page into separate Ajax calls so that even though the page was cached (implicitly or explicitly) the parts of it that updated continued to be updated through the (non-cached) Ajax calls. However, you'll want to create fallback entries for said Ajax calls if you want them to behave nicely when offline (or handle the resulting Ajax errors if not).

Related

Exclude page self by appcache

I have an appcache (with NETWORK *). So now I visit my page with <html manifest="/cache.appcache">. Then the page itself is cached as all the images are. But I want the page self to not be cached. How can I do this? I thought NETWORK * would do the trick.
Regards,
Kevin
The appcache manifest always caches the master page.
If you are using Chrome check the cached files for your page here: chrome://appcache-internals
A workaround could be to put a hidden iframe somewhere on your page, which contains the appcache file to cache offline content. (take a look at "Preventing the application cache from storing masters with an iframe" here: http://labs.ft.com/2012/11/using-an-iframe-to-stop-app-cache-storing-masters/ )
A better solution could be to write your page to fetch new content from your server when it is opened - if the server cannot be reached, it can serve the last known content from the HTML5 local storage.
I have tried the iframe work around, and find it ripe with errors. Most browsers cache the data for the iframe where the page cannot get it.
Instead make the page's content load via AJAX. Basically have a blank html page with the manifest and javascript which pulls and adds its content from the server. This way only the blank html is cached, and content is always updated from the server.
Converting a page to this method can be very difficult, but it works. Making sure the appropriate javascript gets run at the correct time, probably requires some detangling. Moving around server code which won't be called when pulling from cache to the new ajax method.
Note: no need to pull conditional content from the server if the condition is in the query string, different query strings make a separate cache

Selective clearing of items in HTML5 application cache

The HTML5 application cache API requires the browser to re-load all files declared in the CACHE section of the manifest file (when the manifest file has changed and update is called on the applicationCache API).
My manifest file contains thousands of entries. Are there any tricks to telling the browser to only re-load files that have changed?
I faced similar problems caused by the lack of control over the caching behavior of files listed in the cache manifest. Turns out you can gain some control over this process by using iFrames.
The strategy is to divide your thousands of files listed in your main cache manifest into separate (and more manageable cache manifests) then create a lot of dummy HTML pages, each of them referencing a cache manifest. Then, for each dummy HTML, you add an iFrame linking to it into your main HTML document. You can put the iFrames inside an invisible div, which will make the trick invisible to the user.
When each iFrame loads, its checks its individual cache manifest. If any files within that cache manifest changed, then the iFrame will only cache its subgroup of files. You can intelligently group related files together, depending on how much you expect them to change.
What's even better is that you can dynamically insert iFrames on your main HTML at any point of the user's interaction, and only when the iFrame is loaded, the caching progress will be triggered.

My HTML5 Application Cache Manifest is caching everything

UPDATE:
** I posted this question when this feature was really new, I realize now that this feature should not be used this way unless it is used via JavaScript. but seems like this hack is a great solution for most beginners who make the same mistake and misuse of this feature. If you want to cache everything except your HTML this should be done with JS or you could use the solution below **
I guess my question boils down to this:
If the file referencing the manifest using the manifest attribute of the HTML tag falls under the MASTER CACHE ENTRIES how could you have a dynamic page use the manifest.
My file looks like this:
CACHE MANIFEST
CACHE:
# IMAGES:
/stylesheets/bg.jpg
/stylesheets/cont_bg.png
#and so forth..
#EXTERNAL
http://chat.mydomain.com/themes/images/panel_bg.png
http://chat.mydomain.com/themes/images/images_core.png
####################################
#STYLE SHEETS:
/stylesheets/min.css
/stylesheets/css_night.aspx
#####################################
#JAVASCRIPT:
/JAVASCRIPT/header_javascript.js
#EXTERNAL:
http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js
http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
FALLBACK:
/ /offline.php
NETWORK:
*
Now the problem is once I browse a page not in the manifest, my actual dynamic php files like index.php, when I first see the page and there in no cache chrome goes:
Adding master entry to Application Cache with manifest http://208.109.248.197/manifest.appcache
Application Cache Downloading event
Application Cache Progress event (0 of 28)
...
Application Cache Progress event (28 of 28)
Application Cache NoUpdate event
So far so good until I actually load a page, and chrome goes:
Application Cache UpdateReady event
Adding master entry to Application Cache with manifest http://mydomain.com/manifest.appcache
now as you can see in the last line it adds index.php to my application cache and I have verified this by going to url: chrome://appcache-internals/
It says:
Flags URL Size (headers and data)
Explicit, http://mydomain/JAVASCRIPT/header_javascript.js 57.5 kB
Master, http://mydomain/home.php 51.2 kB
Master, http://mydomain/index.php 53.5 kB
Master, Fallback, http://mydomain/offline.php 49.4 kB
where things like index.php and home.php are not supposed to be cached. I would like to tell it to not cache any html extensions if possible. But here is what I have learned from various RFC I believe:
An online whitelist wildcard flag, which is either open or blocking.
The open state indicates that any URL not listed as cached is to be implicitly treated as being in the online whitelist namespaces; the blocking state indicates that URLs not listed explicitly in the manifest are to be treated as unavailable.
well I would like to use one of these online white-list wildcard flags and set it to blocking but I can not find any explanations or examples further more.
I also read:
zero or more URLs that form the online whitelist namespaces.
These are used as prefix match patterns, and declare URLs for which the user agent will ignore the application cache, instead fetching them normally (i.e. from the network or locale HTTP cache as appropriate).
I would also like to use some pattern like this but then again I can find no documentation. Why is there no sign of appcache manifest documentation and no other website I've been to is using it , since my chrome appcache directory shows none!?!?
Thank you for your time!
Here is a hack I found out by playing around:
I haven't found the ultimate answer but from what I've learned it seems that the manifest is not meant to be set on every page. Again I'm not sure but this is a hack that I came across. I have a page such as manifest.html that has the
<html manifest="manifest.appcache">
I learned that pages which do not have this will not be added to the cache however they will still continue using the application cache if on the same domain. Therfore if you include manifest.html a plain html page that has this in an iframe on everypage it will not cache that page like chrome will no longer output:
Adding master entry to Application Cache with manifest
but if you go to network tab you will see that it is using the cache
<iframe id='manifest_iframe_hack'
style='display: none;'
src='temporary_manifest_hack.html'>
</iframe>
content of temporary_manifest_hack.html:
<!DOCTYPE HTML>
<html lang="en" class="no-js" manifest="manifest.appcache">
<head>
<meta charset="utf-8">
<title>Hack 4 Manifest</title>
</head>
<body></body>
</html>
The appcache always contains the page that contains the manifest attribute in the html tag.
If you want that page itself to be dynamic, you must load content into it with an ajax call to a service that is in the NETWORK section.
I guess the Iframe-workaround doesn't work. If you think the files are loaeded from appcache: no. they're coming from browser cache.
disable browsercache in devtools-settings und look at "network". you can see, that all elements will be loaded via network and don't come frome (app)cache.

Omit current page from HTML5 offline appcache but use cached resources

For performance purposes, I want to have some of my web pages use resources that have been cached for offline use (images, CSS, etc.) but to not have the page itself cached as the content will be generated dynamically.
One way to do this would be to refactor my pages so that they load the dynamic content via AJAX or by looking things up in LocalStorage. Details may vary, but broadly speaking, something like that.
If it's possible, I'd prefer to find a way to simply instruct the browser to use cached resources (again, images, CSS, etc.) for the page but to not actually cache the (dynamically generated) HTML content itself.
Is there a way to do that with HTML5 offline appcache? I'm under the impression that the answer is "no" because:
Any page that includes the manifest will be cached so I can't specify the cached resources in the page itself.
There is no way to tell a previous page "use offline assets for this other page but don't actually cache the HTML on that page". You have to specify the page itself, which means the HTML will be cached.
Am I wrong about that? It seems like there is probably some tricky (or not-so-tricky) way around that. Now that I've typed it out, I wonder if including the page explicitly in the NETWORK section of the appcache manifest will do the trick.
My answer is "yes".
I have worked on a web-app where I listed all the necessary resources in the manifest, and set the NETWORK section to *.
The manifest is then included only on the main landing page. So all resources are cached the first time you visit the site and and it works a treat.
In short,
one of your pages must include the manifest and will therefore be cached.
maybe you can have the manifest loaded in a iframe and not have the whole page cached, just a thought.
list all your resources to be cached in the CACHE section
set the NETWORK section to *
I'm fairly certain that the answer to this is no.
If you use the Network section in Chrome, then it shows which resources are loaded from the cache and which are loaded from the server. I have attempted to set the appcache as described above and the resources are always loaded from the server.
Would I be correct in assuming that if the current page is not in the appcache then it wont bother to check in the appcache for any of the resources?
What I've found that is working is to list those files that you don't want cached in appcache in the NETWORK: section of the manifest. For me, that meant adding *.asp* to the network section. Now, none of the classic asp files, or aspx files are cached.

HTML5: Offline Cache is ignored if loading different page under the same URL

I have a web application that has a constant URL and internal state machine. The states are changed via posts. I know it is a bad design and I should use the rest approach. But given this I have a following problem.
I use HTML5 offline cache (the manifest attribute in HTML tag). For the first page it is parsed and cached as I would expect (login page). But for the second page (main menu) the manifest included there is not parsed. No events are shown inside Chrome browser. If I change the URL a little by including a parameter then the manifest is parsed, but not before.
Event if I include everything in the login page manifest the second page downloads the same files again. Event if they are specified in the manifest for the first page.
Why this behaviour?
To answer it myself. It was looking so odd, simply because the cache is only parsed on GET calls and ignored on POST calls. Event if post loads another HTML page. To me this is a little bit silly but it seems that is how it works.
Now it finally works as it is supposed to.