使用 beforeunload 事件的离线 Web 应用程序
Offline web application using beforeunload event
简单地说,我正在尝试在浏览器处于离线状态时为我的网络应用程序提供简单的功能。该功能是一条简单的消息,告诉用户没有网络连接,而不是默认浏览器的页面。我尝试了以下方法:
window.addEventListener("beforeunload", function() {
if (!navigator.onLine){
document.write("There is no network connection."); debugger;return false;
}
}, false);
以上代码适用于 Chrome,但不适用于 firefox。我这里有两个问题:
- 我怎样才能使这个跨浏览器?
- 除了
debugger
还有其他方法吗?
Update
The answer of this question should be an implementation of service-worker
我终于找到了如何为我的网站实现简单的服务工作者。最终结果显示在以下屏幕截图中:
断开客户端机器与网络的连接后,(不离线使用浏览器的开发工具)并执行以下步骤,offline.html
为每个网站页面加载。
我使用了一个生成所需服务代码的在线工具,PWA Builder, I escaped the first step there, Generate Manifest, I started directly with step 2, Build Service Worker. I copied code for website from there, but I have modified some paths to point to the server's root because the code is going to be pasted in laravel应用程序布局,如下所示:
// 在布局的最顶部 HTML
//这是 "Offline page" service worker
//Add this below content to your HTML page, or add the js file to your page at the very top to register sercie worker
if (navigator.serviceWorker.controller) {
console.log('[PWA Builder] active service worker found, no need to register')
} else {
//Register the ServiceWorker
navigator.serviceWorker.register('/pwabuilder-sw.js', { //notice slash in /pwabuilder-sw.js
scope: './'
}).then(function(reg) {
console.log('Service worker has been registered for scope:'+ reg.scope);
});
}
</script>
2- 我复制了 Service worker code 的代码并将其保存在我的应用程序 /public
的 Web 根目录中的一个新文件中作为 pwabuilder-sw.js
还用斜杠更改了一些路径:
//这是"Offline page" service worker
//Install stage sets up the offline page in the cahche and opens a new cache
self.addEventListener('install', function(event) {
var offlinePage = new Request('/offline.html'); //notice /
event.waitUntil(
fetch(offlinePage).then(function(response) {
return caches.open('pwabuilder-offline').then(function(cache) {
console.log('[PWA Builder] Cached offline page during Install'+ response.url);
return cache.put(offlinePage, response);
});
}));
});
//If any fetch fails, it will show the offline page.
//Maybe this should be limited to HTML documents?
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch(event.request).catch(function(error) {
console.error( '[PWA Builder] Network request Failed. Serving offline page ' + error );
return caches.open('pwabuilder-offline').then(function(cache) {
return cache.match('/offline.html'); //notice /
});
}));
});
//This is a event that can be fired from your page to tell the SW to update the offline page
self.addEventListener('refreshOffline', function(response) {
return caches.open('pwabuilder-offline').then(function(cache) {
console.log('[PWA Builder] Offline page updated from refreshOffline event: '+ response.url);
return cache.put(offlinePage, response);
});
});
最后,我使用以下代码创建了 public/offline.html
文件:
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OffLine</title>
<style>
body{
text-align: center;
padding: 1em;
font-family: sans-serif;
font-size: 30px;
}
</style>
</head>
<body>
<img src="data:image/png;base64,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" alt="Disconnected" />
<h1>OffLine</h1>
<p>There is no network connectivity.</p>
<a href="javascript:location.reload()">Click here<a/> to reload after connecting.
</body>
</html>
通知
为了获得更好的测试结果,您可以使用以下提示:
- 清除浏览器的缓存并重新启动它。
- 物理断开机器,例如:关闭 WiFi,当然是在第一次加载网站之后!
另外
我使用 jQuery 在整个应用程序中维护一些 ajax 请求,因此在布局脚本部分,我使用以下代码段在发送之前检测每个 ajax 请求并检查浏览器是否离线,因此它会停止 ajax 请求并提醒消息,然后重新加载页面以加载 offline.html
:
$( document ).ajaxSend(function(evt) {
if (!navigator.onLine){
evt.preventDefault();
swal({
title: '{{__('OffLine Error')}}',
text: '{{__('The browser is offline. Some requests could not be done')}}',
confirmButtonText: '<i class="fox-finalize"></i>{{__('OK')}}',
onClose: function(){
location.reload();
}
})
}
});
简单地说,我正在尝试在浏览器处于离线状态时为我的网络应用程序提供简单的功能。该功能是一条简单的消息,告诉用户没有网络连接,而不是默认浏览器的页面。我尝试了以下方法:
window.addEventListener("beforeunload", function() {
if (!navigator.onLine){
document.write("There is no network connection."); debugger;return false;
}
}, false);
以上代码适用于 Chrome,但不适用于 firefox。我这里有两个问题:
- 我怎样才能使这个跨浏览器?
- 除了
debugger
还有其他方法吗?
Update
The answer of this question should be an implementation of service-worker
我终于找到了如何为我的网站实现简单的服务工作者。最终结果显示在以下屏幕截图中:
断开客户端机器与网络的连接后,(不离线使用浏览器的开发工具)并执行以下步骤,offline.html
为每个网站页面加载。
我使用了一个生成所需服务代码的在线工具,PWA Builder, I escaped the first step there, Generate Manifest, I started directly with step 2, Build Service Worker. I copied code for website from there, but I have modified some paths to point to the server's root because the code is going to be pasted in laravel应用程序布局,如下所示:
// 在布局的最顶部 HTML //这是 "Offline page" service worker
//Add this below content to your HTML page, or add the js file to your page at the very top to register sercie worker if (navigator.serviceWorker.controller) { console.log('[PWA Builder] active service worker found, no need to register') } else { //Register the ServiceWorker navigator.serviceWorker.register('/pwabuilder-sw.js', { //notice slash in /pwabuilder-sw.js scope: './' }).then(function(reg) { console.log('Service worker has been registered for scope:'+ reg.scope); }); } </script>
2- 我复制了 Service worker code 的代码并将其保存在我的应用程序
/public
的 Web 根目录中的一个新文件中作为pwabuilder-sw.js
还用斜杠更改了一些路径://这是"Offline page" service worker
//Install stage sets up the offline page in the cahche and opens a new cache self.addEventListener('install', function(event) { var offlinePage = new Request('/offline.html'); //notice / event.waitUntil( fetch(offlinePage).then(function(response) { return caches.open('pwabuilder-offline').then(function(cache) { console.log('[PWA Builder] Cached offline page during Install'+ response.url); return cache.put(offlinePage, response); }); })); }); //If any fetch fails, it will show the offline page. //Maybe this should be limited to HTML documents? self.addEventListener('fetch', function(event) { event.respondWith( fetch(event.request).catch(function(error) { console.error( '[PWA Builder] Network request Failed. Serving offline page ' + error ); return caches.open('pwabuilder-offline').then(function(cache) { return cache.match('/offline.html'); //notice / }); })); }); //This is a event that can be fired from your page to tell the SW to update the offline page self.addEventListener('refreshOffline', function(response) { return caches.open('pwabuilder-offline').then(function(cache) { console.log('[PWA Builder] Offline page updated from refreshOffline event: '+ response.url); return cache.put(offlinePage, response); }); });
最后,我使用以下代码创建了 public/offline.html
文件:
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OffLine</title>
<style>
body{
text-align: center;
padding: 1em;
font-family: sans-serif;
font-size: 30px;
}
</style>
</head>
<body>
<img src="data:image/png;base64,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" alt="Disconnected" />
<h1>OffLine</h1>
<p>There is no network connectivity.</p>
<a href="javascript:location.reload()">Click here<a/> to reload after connecting.
</body>
</html>
通知
为了获得更好的测试结果,您可以使用以下提示:
- 清除浏览器的缓存并重新启动它。
- 物理断开机器,例如:关闭 WiFi,当然是在第一次加载网站之后!
另外
我使用 jQuery 在整个应用程序中维护一些 ajax 请求,因此在布局脚本部分,我使用以下代码段在发送之前检测每个 ajax 请求并检查浏览器是否离线,因此它会停止 ajax 请求并提醒消息,然后重新加载页面以加载 offline.html
:
$( document ).ajaxSend(function(evt) {
if (!navigator.onLine){
evt.preventDefault();
swal({
title: '{{__('OffLine Error')}}',
text: '{{__('The browser is offline. Some requests could not be done')}}',
confirmButtonText: '<i class="fox-finalize"></i>{{__('OK')}}',
onClose: function(){
location.reload();
}
})
}
});