Dynamically Trigger HTML5 Cache Manifest file?

浪尽此生 提交于 2019-11-27 14:37:31
darkpenguin

After many weeks spent with offline caching, the answer is no, you either cache or don't cache, setting the cache attribute on the client side has no effect.

You could consider offering an alternate url for the caching version, be aware that the page is also implicitly cached as a "master entry".

I am at a loss to understand why you would want to offline cache jquery though, since it is likely to be served with very long expiry anyway.

You may wish to consider offline storage as an alternative. Store the text of the scripts and inject them into the DOM on load. If not cached fetch using Ajax and inject the response, as creating a script tag with the src won't load the script.

You dynamically trigger caching by adding an iframe that points to an empty page containing the actual cache manifest.

offline.html:

<!DOCTYPE html>
<html manifest="offline.appcache">
<head>
    <title></title>
</head>
<body>
</body>
</html>

Make sure to add index.html to the cache manifest. Then just add something like:

<iframe src="offline.html" width="0" height="0">

to document.body dynamically to trigger caching.

Depending on your application, it may be possible to use a modified version of @schibum's approach by breaking down your app into "mini" apps, then caching the sub-sections in an iframe. Consider this example:

index.html

<html manifest="indexx.manifest">
<head>
    <script src="jquery-2.1.4.min.js"></script>
    <script src="index.js"></script>
    <title>Index</title>
</head>
<body>
    <ul>
        <li><a href="1.html">One</a>
        <li><a href="2.html">Two</a>
        <li><a href="3.html">Three</a>
    </ul>
    <iframe id="if" />
</body>
</html>

index.manifest

CACHE MANIFEST
# 3
index.html
jquery-2.1.4.min.js 
index.js

index.js

$( document).ready(function() {
    var pages = ['1.html','2.html','3.html'];
    var LoadNext = function() {
        alert(pages[0]);
        page = pages.shift();
        alert(page)
        if ( page !== undefined ) {
            console.log("Attempting to load " + page);
            $('#if').attr('src', page)
        } else {
            console.log("All done");
        }
    };
    $('#if').load(function() {
        console.log("Finished loading");
        LoadNext()
    });
    LoadNext(); 
});

1.html

<html manifest="1.manifest">
<head>
    <title>One</title>
</head>
<body>
    <img src="1.jpg" width="50%">
</body>
</html>

1.manifest

CACHE MANIFEST
# 2
1.html
1.jpg

{2,3}.{html,manifest} follow 1.{html,manifest}'s form.

As a result, each sub-page (1.html, 2.html, 3.html) have their own manifest, and are thus cached independently. index.html has its own (minimal) manifest, so caching that unconditionally is not nearly as network-heavy as caching the entire app. Then the javascript is responsible for pre-loading every page in the iframe so that it gets cached.

Load index.html, then go offline and see how the sub-pages work. too.

An obvious drawback is that any assets shared between pages (e.g. jQuery) must be redundantly cached.

One thing you must remember. Do not cache the manifest file itself. So all you need to do is refresh the page with a different version of the manifest file according for your user selection. You can dynamically generate the manifest file itself, any change to that file will cause a cache refreshment. Best practice to trigger re-caching is to change the version of the manifest file, something like: # ver1 - 01/01/2018 to # ver2 - 02/02/2018 will do the trick. So you cannot change it in client side but you can do it server side.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!