如何使用服务人员响应导航请求?

时间:2020-03-19 18:24:06

标签: javascript service-worker

在缓存方面,我试图在服务人员的帮助下构建PWA,一切顺利。但是我遇到了一个奇怪的问题。当应用离线时,我无法通过SW提供资产。看来,SW总是无法响应“导航”请求。

未捕获(承诺)TypeError:无法获取

this.addEventListener('fetch', async event => {


event.respondWith(
    (async function() {
      const requestObj = event.request;
      console.log(event);
  const urlParts = requestObj.url.split('/');
  const fileName = urlParts[urlParts.length - 1];
  const fileExtension = fileName.split('.')[fileName.split('.').length - 1];
  if (requestObj.method === 'GET') {

    if (requestObj.mode === 'navigate' && event.request.headers.get('accept').includes('text/html')) {
      console.log('Navigating', requestObj);

      const urlParts = requestObj.url.split('/');
      console.log(urlParts);

      console.log('looking for another option...');
      caches.match(event.request).then(function(response) {
        return response || fetch(event.request);
      });
    }

    // If its an image, then save it if it is in '.png' format
    if (fileExtension === 'jpg' || requestObj.destination === 'image') {
      caches
        .match(requestObj)
        .then(res => {
          if (!res) {
            throw new TypeError('Bad response status');
          } else {
            return res;
          }
        })
        .catch(() => {
          fetch(requestObj).then(response => {
            console.log(response);
            if (response.ok || (response.type === 'opaque' && response.status === 0)) {
              caches.open('v1').then(cache => {
                cache.put(requestObj, response);
              });
            }
            return response;
          });
          return fetch(requestObj);
        });
    }
    ///////////////////////

    if (
      requestObj.destination === 'script' ||
      requestObj.destination === 'style' ||
      requestObj.destination === 'font'
    ) {
      caches
        .match(requestObj)
        .then(response => {
          if (response) {
            return response;
          } else {
            throw new TypeError('Bad response status');
          }
        })
        .catch(() => {
          fetch(requestObj).then(res => {
            if (res.ok) {
              caches.open('v1').then(cache => {
                cache.put(requestObj, res);
              });
            }
            return res.clone();
          });
        });
    }

    //////////////////////
  }
  return fetch(requestObj);
})()


);
});

1 个答案:

答案 0 :(得分:1)

我认为您不需要在获取事件处理程序中使用异步函数,caches.match返回一个Promise,因此足以作为respondWith方法的参数

self.addEventListener('fetch', event => {

    event.respondWith(

        caches.match(event.request).then(function(response) {
            const requestObj = event.request;
            console.log(event);
            const urlParts = requestObj.url.split('/');
            const fileName = urlParts[urlParts.length - 1];
            const fileExtension = fileName.split('.')[fileName.split('.').length - 1];
            if (requestObj.method === 'GET') {

                if (requestObj.mode === 'navigate' && event.request.headers.get('accept').includes('text/html')) {
                    console.log('Navigating', requestObj);

                    const urlParts = requestObj.url.split('/');
                    console.log(urlParts);

                    console.log('looking for another option...');
                    caches.match(requestObj).then(function(response) {
                        return response || fetch(event.request);
                    });
                }


                // If its an image, then save it if it is in '.png' format
                if (fileExtension === 'jpg' || requestObj.destination === 'image') {
                    caches
                    .match(requestObj)
                    .then(res => {
                        if (!res) {
                        throw new TypeError('Bad response status');
                        } else {
                        return res;
                        }
                    })
                    .catch(() => {
                        fetch(requestObj).then(response => {
                        console.log(response);
                        if (response.ok || (response.type === 'opaque' && response.status === 0)) {
                            caches.open('v1').then(cache => {
                            cache.put(requestObj, response);
                            });
                        }
                        return response;
                        });
                        return fetch(requestObj);
                    });
                }
                ///////////////////////

                if (
                    requestObj.destination === 'script' ||
                    requestObj.destination === 'style' ||
                    requestObj.destination === 'font'
                ) {
                    caches
                    .match(requestObj)
                    .then(response => {
                        if (response) {
                        return response;
                        } else {
                        throw new TypeError('Bad response status');
                        }
                    })
                    .catch(() => {
                        fetch(requestObj).then(res => {
                        if (res.ok) {
                            caches.open('v1').then(cache => {
                            cache.put(requestObj, res);
                            });
                        }
                        return res.clone();
                        });
                    });
                }

                return fetch(requestObj);

            }          

        })

    )

});