我想从一个简单的 API 获取响应,用它来创建一系列 URL(一个数组),然后我想将其提供给服务 worker ,并让它将每个条目添加到离线存储中。
作为背景,我对 sw-precache (sw-precache-webpack-plugin)、sw-toolbox 和一般 JavaScript 的经验有限,尽管这种情况正在发生变化。目前有一个 webpack + vue 设置从我很久以前构建的一个简单 API 获取数据。
访问我网站的用户可能希望离线使用一种或多种类型的内容 - 这可能需要 30 个请求(30 个单独的 URL)添加到缓存,最多 4000 个以上。上限预计会随着时间的推移而增加。以我之前尝试过的方式运行 Cache.addAll() 会使客户端崩溃 - 一次请求太多。我认为 importScripts 选项可能是我需要的东西,但我不确定从哪里开始。我如何编写一个脚本来作为我可以向其发送数组的服务 worker 的补充?
总结:
- 使用 webpack/vue
- 基本熟悉 sw-precache 和 sw-toolkit
- 需要在一个用户请求中缓存数万到数千个页面
- 想知道如何着手开发解决方案 问题,例如 importScripts 的示例代码片段,或 另一个可以解决问题的 webpack 插件,或其他替代方案 包含 Service Worker 的方法。
开发代码:https://laoadventist.info
用于获取缓存 URL 的简单 API:https://laoadventist.info/api/r2
我想缓存的单个示例 API 结果(单击一个按钮需要数万个请求):.../api/d
更新:
我能够想出一个有点实用的解决方案......它并不完美,或者在 service worker 中,但它确实有效。欢迎提出改进建议。
var temparray
var tempposition
let processCache = function (array, position) {
if (typeof array === 'undefined') {
array = []
}
if (array.length > 0) {
let chunk = array.shift()
temparray = array
tempposition = position
caches.open('testing')
.then((cache) => { cache.addAll([chunk]) })
.then(function () { processCache(temparray, tempposition) })
}
}
最佳答案
选项1:使用webpack
Webpack 用户可以从 webpack-offline-plugin 中受益它维护得很好,工作也很好。但是,在运行时您仍然需要为动态缓存编写一些代码。对于动态缓存,请引用插件维护者的建议:here
选项 2:自己制作
在你的主包文件中注册 Service Worker
假设:您的服务 worker 文件名为 sw.js
,它位于您网站的根文件夹中。
if ('serviceWorker' in navigator) {
// Recommended to register onLoad
window.addEventListener('load', function() {
navigator.serviceWorker.register('/sw.js');
});
}
在 sw.js
中:安装静态
self.addEventListener('install', function(event) {
self.skipWaiting();
event.waitUntil(
caches.open('static-files-v1').then(function(cache) {
return cache.addAll(['/', 'someFile.js', 'someFile.css']);
})
);
});
在 sw.js
中:获取已安装的静态数据
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(response) {
return response || fetch(event.request)
})
);
});
更多高级步骤
在 sw.js
中:在获取时缓存动态 URL
fetch 事件将监听通过 HTTPS 获取到您网站的任何内容,请阅读我的评论以帮助理解 snipper。
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.open('dynamic-content-v1').then(function(cache) {
// check if the requested URL is inside the dynamic-content-v1
return cache.match(event.request).then(function (response) {
// when found, respond with it.
// when not found: return it as it is after taking a clone
// and storing it, so next visit to the URL it will be there
return response || fetch(event.request).then(function(response) {
cache.put(event.request, response.clone());
return response;
});
});
})
);
});
默认情况下,这种方法不是一个很好的做法,特别是如果您有数千个页面、内容和图像。您不想让用户膨胀并使用您所有的缓存存储配额。请考虑仅缓存要首先显示的重要内容并保持最新,因为您不想发送过时的信息。
选项3和重要说明:
重要提示:您不需要软件即可将动态内容添加到缓存 API。他们都是两个不同的东西。随意从框架组件\异步路由或其他任何内容中获取并添加到缓存 API。
对您的 fiddle 的建议和建议:
我不太确定我是否 100% 了解您在做什么。我可以看到递归函数,但不确定您为什么需要它或其中发生了什么。以下是有关如何从组件内部动态缓存的片段:
// in case browser doesn't support cache
var URL_2_CACHE = '/content/important.html';
if (!('caches' in window)) return;
fetch(new Request(URL_2_CACHE)).then(function(response){
return caches.open('dynamic-cahce-v1').then(function(cache) {
// DONE!
return cache.put(URL_2_CACHE, response);
});
});
现在 HTML 页面已存储在缓存中,SW 将在下一次请求时从那里获取它。
关于javascript - 如何创建一个简单的服务 worker 来添加新项目以离线缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43905334/