渐进式 Web 应用程序:连接再次启动时如何检测和处理
Progressive Web App: How to detect and handle when connection is up again
使用 PWA,我们可以在离线模式下处理设备连接断开的情况。但是我们如何检测固定网络连接并自动 reload/re-activate 应用程序?
我见过的大多数服务都使用以下做法:随着超时增加到某个值,尝试联系服务器。当达到最大超时值时,会出现一个带有手动重新连接按钮的指示器,指示下一次重新连接尝试发生的次数
您可以监视 offline
and online
events, which are widely supported。此外,您可以通过尝试从目标服务器 URL:
获取 HEAD
来测试连接性
// Test this by running the code snippet below and then
// use the "Offline" checkbox in DevTools Network panel
window.addEventListener('online', handleConnection);
window.addEventListener('offline', handleConnection);
function handleConnection() {
if (navigator.onLine) {
isReachable(getServerUrl()).then(function(online) {
if (online) {
// handle online status
console.log('online');
} else {
console.log('no connectivity');
}
});
} else {
// handle offline status
console.log('offline');
}
}
function isReachable(url) {
/**
* Note: fetch() still "succeeds" for 404s on subdirectories,
* which is ok when only testing for domain reachability.
*
* Example:
* https://google.com/noexist does not throw
* https://noexist.com/noexist does throw
*/
return fetch(url, { method: 'HEAD', mode: 'no-cors' })
.then(function(resp) {
return resp && (resp.ok || resp.type === 'opaque');
})
.catch(function(err) {
console.warn('[conn test failure]:', err);
});
}
function getServerUrl() {
return document.getElementById('serverUrl').value || window.location.origin;
}
<fieldset>
<label>
<span>Server URL for connectivity test:</span>
<input id="serverUrl" style="width: 100%">
</label>
</fieldset>
<script>document.getElementById('serverUrl').value = window.location.origin;</script>
<p>
<i>Use Network Panel in DevTools to toggle Offline status</i>
</p>
一个 technique 处理这个:
线下活动
- 离线显示icon/status
- 仅启用离线可用的功能(通过缓存数据)
线上活动
- 在线展示icon/status
- 启用所有功能
注意 online
事件,它只在连接时通知设备。它可以连接到 WiFi 热点,而无需实际的互联网连接(例如,由于凭据)。
PWA 中的一个常见做法是对您的应用程序遵循 Application Shell 方法。这将允许您在进入时缓存应用程序 Shell,然后根据连接加载数据。
在这种方法中,最常用的缓存和服务方法是从缓存提供回退到网络,只要请求的资源在缓存中不可用,您就会通过网络发送请求并缓存响应。然后从缓存中提供服务。
这允许在连接不稳定时(例如在火车上)进行更优雅的降级。
一个实现的例子:
const cacheName = "my-cache-v1"
self.addEventListener('fetch', (event) => {
if (event.request.method === 'GET') {
event.respondWith(
caches.match(event.request).then((response) => {
if (response) {
return response;
}
return fetch(event.request).then((response) => {
return caches.open(cacheName).then((cache) => {
cache.put(event.request.url, response.clone());
return response;
});
});
})
);
}
});
在上面的示例中(只是 Service Worker 生命周期中的必需步骤之一),您还需要删除过时的缓存条目。
使用 PWA,我们可以在离线模式下处理设备连接断开的情况。但是我们如何检测固定网络连接并自动 reload/re-activate 应用程序?
我见过的大多数服务都使用以下做法:随着超时增加到某个值,尝试联系服务器。当达到最大超时值时,会出现一个带有手动重新连接按钮的指示器,指示下一次重新连接尝试发生的次数
您可以监视 offline
and online
events, which are widely supported。此外,您可以通过尝试从目标服务器 URL:
HEAD
来测试连接性
// Test this by running the code snippet below and then
// use the "Offline" checkbox in DevTools Network panel
window.addEventListener('online', handleConnection);
window.addEventListener('offline', handleConnection);
function handleConnection() {
if (navigator.onLine) {
isReachable(getServerUrl()).then(function(online) {
if (online) {
// handle online status
console.log('online');
} else {
console.log('no connectivity');
}
});
} else {
// handle offline status
console.log('offline');
}
}
function isReachable(url) {
/**
* Note: fetch() still "succeeds" for 404s on subdirectories,
* which is ok when only testing for domain reachability.
*
* Example:
* https://google.com/noexist does not throw
* https://noexist.com/noexist does throw
*/
return fetch(url, { method: 'HEAD', mode: 'no-cors' })
.then(function(resp) {
return resp && (resp.ok || resp.type === 'opaque');
})
.catch(function(err) {
console.warn('[conn test failure]:', err);
});
}
function getServerUrl() {
return document.getElementById('serverUrl').value || window.location.origin;
}
<fieldset>
<label>
<span>Server URL for connectivity test:</span>
<input id="serverUrl" style="width: 100%">
</label>
</fieldset>
<script>document.getElementById('serverUrl').value = window.location.origin;</script>
<p>
<i>Use Network Panel in DevTools to toggle Offline status</i>
</p>
一个 technique 处理这个:
线下活动
- 离线显示icon/status
- 仅启用离线可用的功能(通过缓存数据)
线上活动
- 在线展示icon/status
- 启用所有功能
注意 online
事件,它只在连接时通知设备。它可以连接到 WiFi 热点,而无需实际的互联网连接(例如,由于凭据)。
PWA 中的一个常见做法是对您的应用程序遵循 Application Shell 方法。这将允许您在进入时缓存应用程序 Shell,然后根据连接加载数据。
在这种方法中,最常用的缓存和服务方法是从缓存提供回退到网络,只要请求的资源在缓存中不可用,您就会通过网络发送请求并缓存响应。然后从缓存中提供服务。
这允许在连接不稳定时(例如在火车上)进行更优雅的降级。
一个实现的例子:
const cacheName = "my-cache-v1"
self.addEventListener('fetch', (event) => {
if (event.request.method === 'GET') {
event.respondWith(
caches.match(event.request).then((response) => {
if (response) {
return response;
}
return fetch(event.request).then((response) => {
return caches.open(cacheName).then((cache) => {
cache.put(event.request.url, response.clone());
return response;
});
});
})
);
}
});
在上面的示例中(只是 Service Worker 生命周期中的必需步骤之一),您还需要删除过时的缓存条目。