离线时在 Progressive Web App 中处理获取请求
Posted
技术标签:
【中文标题】离线时在 Progressive Web App 中处理获取请求【英文标题】:Handling fetch requests in Progressive Web App when offline 【发布时间】:2017-06-28 04:32:39 【问题描述】:我一直在关注渐进式 Web 应用程序上的 this tutorial,我正在尝试找到一种在应用程序离线时向用户呈现某种消息的方法。到目前为止,我的代码与教程几乎相同:
var cacheName = 'demoPWA-v1'; var filesToCache = [ '/', '/index.html', '/js/app.js', '/icons/pwa-256x256.png' ]; self.addEventListener('install', function(e) console.log('[demoPWA - ServiceWorker] 安装事件已触发。'); e.等待直到( caches.open(cacheName).then(function(cache) console.log('[demoPWA - ServiceWorker] 缓存应用程序外壳...'); 返回 cache.addAll(filesToCache); ) ); ); self.addEventListener('activate', function(e) console.log('[demoPWA - ServiceWorker] 激活事件被触发。'); e.等待直到( caches.keys().then(function(keyList) 返回 Promise.all(keyList.map(function(key) 如果(键!==缓存名称) console.log('[demoPWA - ServiceWorker] 删除旧缓存...', key); 返回缓存。删除(键); )); ) ); 返回 self.clients.claim(); ); self.addEventListener('fetch', function(e) console.log('[demoPWA - ServiceWorker] Fetch 事件被触发。', e.request.url); e.respondWith( caches.match(e.request).then(function(response) 如果(响应) console.log('[demoPWA - ServiceWorker] 从缓存中检索...'); 返回响应; console.log('[demoPWA - ServiceWorker] 从 URL 检索...'); 返回获取(e.request); ) ); );当我在 Chrome 中的 Application > Service Workers
下选中 Offline 复选框时,我收到了一些错误,如下所示:
我想知道是否有某种方法可以处理此错误,并在这样做的同时向用户显示某种消息,告知他们他们处于离线状态。
【问题讨论】:
获取,返回一个承诺。所以你可以抓住错误..fetch(e.request).catch(function (e) (*do your stuff*)
@Keith 您能否根据该逻辑发布答案?如果可以的话,也许可以更详细地解释一下。
可以,但是您会以什么方式通知用户?.. 最简单的就是使用警报,例如现在可以吗?
@Keith 我想将消息写入一些 HTML 元素,但是为了展示解决方案,警报会做!
【参考方案1】:
以下是仅用于发出警报的模块,然后您可以将警报更改为使用 Jquery 或直接 DOM 来更新您的 HTML 页面..
self.addEventListener('fetch', function(e)
console.log('[demoPWA - ServiceWorker] Fetch event fired.', e.request.url);
e.respondWith(
caches.match(e.request).then(function(response)
if (response)
console.log('[demoPWA - ServiceWorker] Retrieving from cache...');
return response;
console.log('[demoPWA - ServiceWorker] Retrieving from URL...');
return fetch(e.request).catch(function (e)
//you might want to do more error checking here too,
//eg, check what e is returning..
alert('You appear to be offline, please try again when back online');
);
)
);
);
【讨论】:
事实证明,虽然这个想法很可靠,但我无法显示服务人员的警报。 (当你最初发布它时,我没有测试你的答案,因为我离开了我的电脑,并认为这样一个简单的解决方案肯定会起作用,但事实证明服务工作者有一些限制......) 我从来没有真正需要在 javascript 中使用 service workers,但是当我在 Win32 开发中使用 Thread 时,当你需要更新 GUI 时,你会向主线程发布消息。快速浏览在 Service Worker 中,您似乎也想在这里做同样的事情。 从服务人员向主线程发布消息。然后从那里处理警报/DOM 更新。【参考方案2】:是的,你在做什么,这很有意义,只要你确定缓存不为空,因为你只是打算用它来显示离线警告。
MDN代码真的有问题catch()不工作,我做了一些修改,成功了,至于catch(),我还没来得及解决问题,如果你先找到解决方案,让我知道!代码如下:
var CACHE_VERSION = 1;
// Smallest identifier for a specific version of the cache
var CURRENT_CACHES =
font: 'OFFLINE_CACHE' + CACHE_VERSION
;
self.addEventListener('fetch', function(event)
// console.log(event);
// We only want to call event.respondWith() if this is a GET request for an HTML document.
if (event.request.method === 'GET')
console.log('Handling fetch event for', event.request.url);
event.respondWith(
// Opens the cache object that starts with 'font'
caches.open(CURRENT_CACHES['font']).then(function(cache)
return cache.match(event.request).then(function(response)
if (response)
console.log('Found cached answer:', response);
return response;
else
//Did not find answer in cache
return fetch(event.request).then(function(fetchresponse)
console.log("Request Result - redirected:" + fetchresponse.redirected + ", status:" + fetchresponse.status + ", statusText:" + fetchresponse.statusText + ", type:" + fetchresponse.type + ", url:" + fetchresponse.url);
if(fetchresponse.status == '200' || fetchresponse.status == '201' || fetchresponse.status == '202' || fetchresponse.status == '203' || fetchresponse.status == '204' || fetchresponse.status == '206')
return fetchresponse;
else
console.log('The request returned http code 30*, 40* or 50*.');
return false;
).catch(function(e)
//Offline version
return new Response('<html><title></title><strong>Sorry, You are offline!</strong></html>', "status" : 202, "headers" : "Content-Type" : "text/html; charset=utf-8");
);
).catch(function(error)
//This .catch () doesn't seem to work, as I said, but it won't give you any problems, it just takes up space.
// Handles exceptions that come from match () or fetch ().
console.error(' Error:', error);
throw error;
);
)
);
;
);
【讨论】:
以上是关于离线时在 Progressive Web App 中处理获取请求的主要内容,如果未能解决你的问题,请参考以下文章