仅在脱机时使用ServiceWorker缓存

时间:2015-10-09 19:09:58

标签: javascript browser-cache web-worker service-worker

我正在尝试将服务工作者集成到我的应用程序中,但我发现服务工作者即使在线也尝试检索缓存内容,但我希望它在这些情况下更喜欢网络。我怎样才能做到这一点?下面是我现在的代码,但我认为它不起作用。为简洁起见,省略了SW安装代码。

var CACHE_NAME = 'my-cache-v1';
var urlsToCache = [
  /* my cached file list */
];

self.addEventListener('install', function(event) {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

/* request is being made */
self.addEventListener('fetch', function(event) {
  event.respondWith(
    //first try to run the request normally
    fetch(event.request).catch(function() {
      //catch errors by attempting to match in cache
      return caches.match(event.request).then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
      });
    })
  );
});

这似乎导致像The FetchEvent for "[url]" resulted in a network error response: an object that was not a Response was passed to respondWith().这样的警告,我是服务工作者的新手,所以对任何错误的术语或不良做法表示道歉,欢迎任何提示。谢谢!

3 个答案:

答案 0 :(得分:10)

如果不对此进行测试,我的猜测是,在没有缓存匹配的情况下,您没有正确解析respondWith()According to MDN,传递给respondWith()的代码应该“通过将响应或网络错误返回到Fetch来解决”。那么为什么不尝试这样做:

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

答案 1 :(得分:5)

为什么不打开fetch事件的缓存? 我认为服务工作者的过程是:

  • 打开缓存

  • 检查请求是否与缓存中的答案匹配

  • 然后你回答

OR(如果答案不在缓存中):

  • 通过网络检查请求

  • 从网络克隆答案

  • 将请求和克隆的答案放在缓存中以备将来使用

我会写:

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.open(CACHE_NAME).then(cache => {
     return cache.match(event.request).then(response => {
      return response || fetch(event.request)
      .then(response => {
        const responseClone = response.clone();
        cache.put(event.request, responseClone);
        })
      })
    }
 );
});

答案 2 :(得分:2)

event.respondWith() expects a promise that resolves to Response。因此,如果发生高速缓存未命中的情况,您仍然需要返回响应,但是在上面,您什么也不返回。我也将尝试先使用缓存,然后再获取,但是无论如何,作为最后的选择,您始终可以创建合成的Response,例如:

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: activemq
  namespace: dev
  labels:
    app: activemq
spec:
  replicas: 1
  serviceName: activemq-svc
  selector:
    matchLabels:
      app: activemq
  template:
    metadata:
      labels:
        app: activemq
    spec:
      securityContext:
        runAsUser: 1000
        fsGroup: 2000
        runAsNonRoot: false
      containers:
       - name: activemq
         image: "mydocker/amq:latest"
         imagePullPolicy: "Always"
         ports:
          - containerPort: 61616
            name: port-61616
          - containerPort: 8161
            name: port-8161
         volumeMounts:
          - name: activemq-data
            mountPath: "/opt/activemq/data"
      restartPolicy: Always
      imagePullSecrets:
       - name: regsecret
      tolerations:
        - effect: NoExecute
          key: appstype
          operator: Equal
          value: ibd-mq
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: appstype
                operator: In
                values:
                - dev-mq

  volumeClaimTemplates:
   - metadata:
       name: activemq-data
     spec:
       accessModes:
        - ReadWriteOnce
       storageClassName: "gp2-us-east-2a"
       resources:
         requests:
           storage: 100Gi