javascript 动态触发 HTML5 缓存清单文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4548342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 14:04:57  来源:igfitidea点击:

Dynamically Trigger HTML5 Cache Manifest file?

javascriptcachinghtmloffline

提问by mikechambers

I am using the new cache manifest functionality from HTML5 to cache my web app so it will work offline. The content is cached automatically when the page is loaded with the following html element:

我正在使用 HTML5 中的新缓存清单功能来缓存我的 Web 应用程序,以便它可以脱机工作。当页面使用以下 html 元素加载时,内容会自动缓存:

<html lang="en" manifest="offline.manifest">

This works fine. However, I want to give my users the option of whether they want the content cached offline. So, here is my question:

这工作正常。但是,我想让我的用户选择他们是否希望离线缓存内容。所以,这是我的问题:

Is there any way to trigger that an application be cached at runtime, using JavaScript, and not have it automatically done when the page is loaded.

有什么方法可以触发应用程序在运行时缓存,使用 JavaScript,而不是在页面加载时自动完成。

For example, something like this (using jquery):

例如,像这样(使用 jquery):

----------------index.html--------------

----------------index.html--------------

<head>
 <meta charset="utf-8" />

 <script src="http://code.jquery.com/jquery-1.4.4.min.js"></script> 
 <script type="text/javascript" src="Main.js"></script> 

</head>
<body>

 <button id="cacheButton">Cache Page</button>

</body>
</html>

---------Main.js---------

---------Main.js---------

$(document).ready(
 function()
 {
  $('#cacheButton').click(onCacheButtonClick);
 }
)

function onCacheButtonClick(event)
{
 console.log("Setting Offline Manifest");
 $('#htmlRoot').attr("manifest","offline.manifest");
}

-------------offline.manifest-------------

-------------offline.manifest-------------

CACHE MANIFEST

#version .85

#root
index.html
scripts/main.js

#jquery assets
http://code.jquery.com/jquery-1.4.4.min.js

Basically, when the button is clicked, I dynamically set the manifest attribute of the html element. This works (in the sense the element is set), but it does not cause the browser to then cache the page.

基本上,当按钮被点击时,我会动态设置 html 元素的 manifest 属性。这有效(在元素被设置的意义上),但它不会导致浏览器缓存页面。

Any suggestions?

有什么建议?

采纳答案by 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".

您可以考虑为缓存版本提供备用 url,请注意该页面也被隐式缓存为“主条目”。

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.

我不知道为什么你想要离线缓存 jquery,因为它可能会在很长的期限内提供服务。

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.

您可能希望考虑将离线存储作为替代方案。存储脚本的文本并在加载时将它们注入 DOM。如果没有使用 Ajax 缓存获取并注入响应,因为使用 src 创建脚本标记不会加载脚本。

回答by schibum

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

您可以通过添加指向包含实际缓存清单的空页面的 iframe 来动态触发缓存。

offline.html:

离线.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:

确保将 index.html 添加到缓存清单。然后只需添加如下内容:

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

to document.body dynamically to trigger caching.

动态到 document.body 以触发缓存。

回答by Flimzy

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:

根据您的应用程序,可以通过将您的应用程序分解为“迷你”应用程序,然后在 iframe 中缓存子部分来使用@schibum 方法的修改版本。考虑这个例子:

index.html

索引.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

索引.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

1.html

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

1.manifest

1.清单

CACHE MANIFEST
# 2
1.html
1.jpg

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

{2,3}.{html,manifest} 遵循 1.{html,manifest} 的形式。

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.

因此,每个子页面(1.html、2.html、3.html)都有自己的清单,因此被独立缓存。index.html 有自己的(最小)清单,因此无条件缓存不像缓存整个应用程序那样占用大量网络资源。然后 javascript 负责预加载 iframe 中的每个页面,以便它被缓存。

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

加载 index.html,然后离线查看子页面如何工作。也。

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

一个明显的缺点是页面之间共享的任何资产(例如 jQuery)都必须被冗余缓存。

回答by Itay Merchav

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.

你必须记住的一件事。不要缓存清单文件本身。因此,您需要做的就是根据您的用户选择使用不同版本的清单文件刷新页面。您可以动态生成清单文件本身,对该文件的任何更改都将导致缓存刷新。触发重新缓存的最佳做法是更改清单文件的版本,例如:#ver1 - 01/01/2018 到 #ver2 - 02/02/2018 即可。所以你不能在客户端改变它,但你可以在服务器端改变它。