如何创建一个简单的服务工作者来添加新项目以脱机缓存? [英] How do I create a simple service worker to add new items to cache offline?

查看:218
本文介绍了如何创建一个简单的服务工作者来添加新项目以脱机缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从简单的API获取响应,使用它来创建一系列URL(数组),然后我想要提供给服务工作者,并将每个条目添加到脱机存储。



对于后台,我对sw-precache(sw-precache-webpack-plugin),sw-toolbox和JavaScript有一定的经验,尽管如此。目前有一个webpack + vue设置从一个很久以前建立的简单的API获取数据。



访问我的网站的用户可能希望有一种或多种类型内容可离线使用 - 这可能需要30个请求(30个单独的URL)的任何地方添加到高达4000个以上的缓存。预期上限将随着时间的推移而增加。运行Cache.addAll()的方式,我尝试之前使客户端崩溃 - 太多的请求一次。我认为importScripts选项可能是我需要的,但不知道从哪里开始。如何编写一个可以作为服务工作人员补充的脚本,我可以发送一个数组?



总结:




  • 使用webpack / vue

  • 基本熟悉sw-precache和sw-toolkit

  • 需要数以万计的页面可能在一个用户请求中缓存

  • 想知道如何开发解决
    问题的解决方案,例如importScripts或
    另一个可以做窍门的webpack插件,或其他包含服务工作者的
    方法。



开发代码: https://laoadventist.info



用于获取URL的简单API: https://laoadventist.info/api/r2



我想缓存的一个单独的示例API结果(一个对接点击需要数万到数千个请求):... / api / d



更新:



我能够提出一个有用的功能解决方案...它不完美,或在服务工作者,但它的工作。欢迎提出改进意见。



  var temparrayvar temppositionlet processCache = function(array,位置){if(typeof array ==='undefined'){array = []} if(array.length> 0){let chunk = array.shift()temparray = array temposition = position caches.open('testing ').then((cache)=> {cache.addAll([chunk])}).then(function(){processCache(temparray,temposition)})}}  

解决方案

选项1:使用webpack



Webpack用户可以受益于 webpack-offline-plugin ,该文件维护良好,做得很好但是,在运行时,您仍然需要编写一些动态缓存代码。对于动态缓存,请参阅插件维护者的此建议:这里



选项2:自己创建



注册主包文件中的服务工作者



假设:您的服务工作者文件称为 sw.js ,它位于您网站的根文件夹中。

  if('serviceWorker'in navigator){
//建议注册onLoad
window.addEventListener('load' function(){
navigator.serviceWorker.register('/ sw.js');
});
}



里面 sw.js :install statics



  self.addEventListener('install',function(event){
self.skipWaiting() ;
event.waitUntil(
caches.open('static-files-v1')然后(function(cache){
return cache.addAll(['/','someFile。 js','someFile.css']);
})
);
});



里面 sw.js :fetch installed statics



  self.addEventListener('fetch',function(event){
event.respondWith(
caches .match(event.request).then(function(response){
return response || fetch(event.request)
})
);
});






更多高级步骤



里面 sw.js :抓取动态URL抓取



fetch事件将听任何东西,一切都通过HTTPS访问您的网站,请阅读我的意见,以帮助了解狙击手。

  self.addEventListener ('fetch',function(event){
event.respondWith(
caches.open('dynamic-content-v1')。then(function(cache){
// check if请求的URL位于dynamic-content-v1
中,返回cache.match(event.request).then(function(response){
//发现时,回应它
/ /当没有找到:返回它,因为它是克隆
//并存储它,所以下次访问的URL将会在那里
返回响应|| fetch(event.request).then (function(response){
cache.put(event.request,response.clone());
return re响应;
});
});
})
);
});

如果您有数千页,内容,这种方法不是很好的做法,默认情况下和图像。您不想使用户膨胀,并使用您的所有缓存存储配额。请考虑缓存只有首先要显示的事项,并保持新鲜,因为您不想发送过时的信息。



Option3和重要注意事项:



重要信息:您不需要SW将动态内容添加到缓存API。他们两个不同的东西。您可以从框架组件\ async路由或其他任何内容中获取并添加缓存API。



关于您的小提琴的建议和建议:



我不太清楚我明白你在做什么100%。我可以看到一个递归函数,但不知道你为什么需要它或在那里发生了什么。以下是关于如何从组件内部动态缓存的代码片段:

  //如果浏览器不支持缓存
var URL_2_CACHE ='/content/important.html';
if(!('caches'in window))return;
fetch(new Request(URL_2_CACHE))然后(function(response){
return caches.open('dynamic-cahce-v1')然后(function(cache){
/ / DONE!
return cache.put(URL_2_CACHE,response);
});
});

现在,HTML页面已经存储在缓存中,SW将在下次请求时从中获取。


I am wanting to take the response from a simple API, use it to create a series of URLs (an array), that I then want to feed to a service worker, and have it add each entry to the offline storage.

For background, I have some limited experience with sw-precache (sw-precache-webpack-plugin), sw-toolbox, and JavaScript in general, though that is changing. Currently have a webpack + vue setup getting data from a simple API I built a long time ago.

A user who visits my site likely wants to have one or more types of content available offline - which might require anywhere from 30 requests (30 individual URLs) to add to cache, up to as many as 4000+. The upper limit would be expected to increase over time. Running Cache.addAll() the way that I've attempted before makes the client crash - too many requests all at once. I think importScripts option may be the thing I need, but am not sure where to start. How do I write a script that would act as a supplement to the service worker which I could send an array to?

To summarize:

  • Using webpack / vue
  • Basic familiarity with sw-precache and sw-toolkit
  • Need tens to thousands of pages possibly cached in one user request
  • Would like to know how to go about developing a solution to the problem, such as snippets of example code for an importScripts, or another webpack plugin that might do the trick, or other alternative methods which incorporate Service Workers.

In Development Code: https://laoadventist.info

Simple API for getting URLs to cahce: https://laoadventist.info/api/r2

An individual example API result that I would like to cache (one button click requires tens to thousands of requests): .../api/d

UPDATE:

I was able to come up with a somewhat functional solution... It's not perfect, or in a service worker, but it does work. Suggestions for improvement are welcome.

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) })
  }
}

解决方案

Option1: Using webpack

Webpack users can benefit from webpack-offline-plugin which is well maintained and does the job well. However, at runtime you will still need to write a little bit of code for dynamic caching. for dynamic caching, please refer to this advise by the plugin maintainer: here

Option2: Make your own

Register The Service Worker in your main bundle file

assumptions: your service worker file called sw.js and it's in the root folder of your website.

if ('serviceWorker' in navigator) {
  // Recommended to register onLoad
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('/sw.js');
  });
}

inside sw.js: install statics

self.addEventListener('install', function(event) {
  self.skipWaiting();
  event.waitUntil(
    caches.open('static-files-v1').then(function(cache) {
      return cache.addAll(['/', 'someFile.js', 'someFile.css']);
    })
  );
});

inside sw.js: fetch installed statics

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(response) {
      return response || fetch(event.request)
    })
  );
});


More Advanced Steps

inside sw.js: cache dynamic URLs on fetch

fetch event will be listening to anything and everything being fetched into your website through HTTPS, please read my comments to help understand the 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;
        });
      });
    })
  );
});

This method is not a very good practice to do by default specially if you have thousands of pages, content and images. You don't want to bloat the user and use all your quota of cache storage. please consider caching only what matters to be shown first and keep it fresh as you don't want to ship outdated info.

Option3 and important note:

IMPORTANT: You do not need SW to add dynamic content to the cache API. they both 2 different things. Feel free to fetch and add to cache API from inside your frameworks components \ async routes or whatever.

suggestions and recommendations about your fiddle:

I'm not quite sure I understand what are you doing 100%. I can see a recursive function but not sure why do you need it or what's going in there. Here's a snippet on how to cache dynamically from inside your component:

// 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);
  });
});

Now that the HTML page has been stored in cache, SW will fetch it from there on next request.

这篇关于如何创建一个简单的服务工作者来添加新项目以脱机缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆