服务人员发送两个请求 [英] Service worker sends two requests

查看:45
本文介绍了服务人员发送两个请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了一个服务工作者,该服务工作者可以缓存所有脱机使用的请求,这可以正常工作.但是,每次我加载页面时,都会有两个请求命中我的Web服务器(一个来自服务工作者,另一个来自浏览器)!

我如何缓存请求并仅将页面加载一次?

service-worker.js

  self.addEventListener('install',function(event){//加载错误页面,如果用户没有互联网,它将显示var errorPage = new Request('/?p = error& offline');event.waitUntil(pushToCache(errorPage));});//如果任何获取失败,它将在高速缓存中查找请求并首先从那里提供服务self.addEventListener('fetch',function(event){event.waitUntil(pushToCache(event.request));event.respondWith(fetch(event.request)//尝试从Internet加载.catch(函数(错误){返回fetchFromCache(event.request);})//没有Internet连接,请尝试从缓存中获取它);});函数pushToCache(request){if(request.method =="GET"){返回caches.open('stm-app').then(function(cache){return fetch(request).then(function(response){返回cache.put(请求,响应);});});}};函数fetchFromCache(request){返回caches.open('stm-app').then(function(cache){返回cache.match(request).then(function(matching){if(!matching || matching.status == 404){返回fetchFromCache(new Request('/?p = error& offline'));//显示用户离线的页面}别的{返回匹配;}});});} 

sw-register.js

  if(导航器中的"serviceWorker"){navigator.serviceWorker.register('service-worker.js').then(function(registration){console.log('Registered:',注册);}).catch(function(error){console.log('注册失败:',错误);});} 

解决方案

因此,只要您提出请求,就会发生以下情况:

  1. 该网页将获取请求发送到服务器,
  2. 服务工作者在提取"事件中拦截请求,
  3. pushToCache() 向服务器触发获取请求,以缓存响应,
  4. 然后,您通过向服务器获取请求来响应事件,这将返回来自Web服务器的响应承诺.

是的,这很有意义,那个东西只向页面最初发出的每个请求发送了两个请求,两个发送给服务器.

您可能要考虑的一件事是首先从缓存中响应,然后在网络上获取最新数据.这样,您可以避免在出现连接问题时延迟加载,并且即使用户在线也可以加快页面的加载时间.

让我们考虑以下情形:用户或服务器都处于脱机状态.触发请求后,它必须超时才能进入promise的catch部分并获取缓存的响应.

拦截事件后,您可以做的是检查缓存是否匹配,如果发现任何内容,请对该事件做出响应.然后启动获取请求以更新缓存.现在,如果找不到任何内容,请触发获取请求,克隆响应(因为响应正文只能使用一次),以原始响应进行响应,然后使用克隆的响应更新缓存.

我们实现了什么?

无论用户是在线,离线还是在Lie-Fi上,该用户都能获得即时响应!

服务器最多收到一个请求,并且缓存将始终使用服务器中的最新数据进行更新!

serviceworke.rs 是一个很好的资源,可以帮助您了解如何与服务工作者一起做很多有趣的事情./p>

此页面特别详细地解释了我怎么说以上作品.

I've implemented a service worker which caches all requests for offline usage, this works fine. But everytime I load a page there are two requests hitting my webserver (one from the service worker and one from the browser)!

How can I cache the request and only load the page once?

service-worker.js

self.addEventListener('install', function(event) {
  //load error page which will show if user has no internet
  var errorPage = new Request('/?p=error&offline');
  event.waitUntil(pushToCache(errorPage));
});

//If any fetch fails, it will look for the request in the cache and serve it from there first
self.addEventListener('fetch', function(event) {
  event.waitUntil(pushToCache(event.request));

  event.respondWith(
    fetch(event.request) //try loading from internet
    .catch(function (error) {
      return fetchFromCache(event.request);
    }) //no internet connection try getting it from cache
  );
});

function pushToCache(request){
  if(request.method == "GET"){
    return caches.open('stm-app').then(function (cache) {
      return fetch(request).then(function (response) {
        return cache.put(request, response);
      });
    });
  }
};

function fetchFromCache(request) {
  return caches.open('stm-app').then(function (cache) {
    return cache.match(request).then(function (matching) {
      if(!matching || matching.status == 404){
        return fetchFromCache(new Request('/?p=error&offline')); //show page that user is offline
      }else{
        return matching;
      }
    });
  });
}

sw-register.js

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('service-worker.js')
  .then(function(registration) {
    console.log('Registered:', registration);
  })
  .catch(function(error) {
    console.log('Registration failed: ', error);
  });
}

解决方案

So here's what happens whenever you make a request:

  1. The webpage sends a fetch request to the server,
  2. the Service Worker intercepts the request on the 'fetch' event,
  3. pushToCache() fires a fetch request to the server in order to cache the response,
  4. then you respond to the event with a fetch request to the server which will return a Promise for a Response from the web server.

Yup, that makes sense, that thing just sent two requests two the server for every request the page originally made.

One thing you might want to consider is responding from the cache first and then going on the network to get the latest data. This way you will avoid delays in loading in the case of connection issues and it will speed up the loading time of the page even when the user is online.

Let's consider the following scenario: Either the user or the server are offline. Once you fire the request, it will have to time out before it goes to the catch part of the promise and get the cached response.

What you could do once you intercept the event is check the caches for a match and if you find anything, respond to the event with that. Then start a fetch request in order to update the cache. Now if you don't find anything, fire a fetch request, clone the response (because the response body can only be used once), respond with the original response and then update the cache with the cloned response.

What did we achieve with that?

The user gets an instant response, no matter if he's online, offline or on Lie-Fi!

The server gets at most one request and the caches will always get updated with the latest data from the server!

serviceworke.rs is a great resource that can help you understand how to do many interesting things with Service Workers.

This page in particular explains in a bit more detail how what I said above works.

这篇关于服务人员发送两个请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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