算法入门 从入门
曾经有一段时间,人们只将推送通知的使用与移动应用程序相关联。 幸运的是,时间已经过去了。 现在有服务人员可以帮助我们在桌面应用程序中实现推送通知,甚至在您离线时也可以打开网站。
服务工作者是在后台运行的脚本。 它不需要网页或用户交互即可工作。 这意味着即使您的网站未打开,即使它无法直接访问DOM,它也将运行(尽管DOM可以使用postMessage
API与Service Worker进行通信)。 当前,它们包括推式通知和地理围栏之类的功能。 它还可以拦截和处理网络请求,这是我们将在本教程中使用的功能。 对于那些对浏览器支持感到好奇的人,我建议在这里看看 。 正如您将看到的,它的实现仍处于早期阶段。
为了演示Service Workers的网络拦截功能如何工作,我们将创建一个静态网站,即使用户处于脱机状态,该网站也可以运行。 您可以在此处找到网站的整个演示 。
服务人员可让您控制网页,您可以在其中以编程方式选择要缓存的组件。 请记住,它只会在第二次访问或后续访问时离线运行。 此行为背后的原因将在本教程的后面部分进行说明。
服务人员的一个普遍问题是,他们只能在“安全来源”(基本上是HTTPS站点)中工作,并且符合一项政策,该政策倾向于使用安全来源来提供强大的新功能 。 但是,即使localhost也被视为安全来源,因此在其上进行开发是避免此错误的简便方法。 如果愿意,您也可以使用GitHub Pages(就像我一样),因为它们是通过HTTP提供的。
入门
我们需要做的第一件事是注册服务工作者。 只有在浏览器支持的情况下,它才起作用。 这意味着您仅在navigator.serviceWorker
存在的情况下,才能在本教程中找到的以下所有代码段均有效。
//make sure that Service Workers are supported.
if (navigator.serviceWorker) {
navigator.serviceWorker.register('./service-worker.js', {scope: './about'})
.then(function (registration) {
console.log(registration);
})
.catch(function (e) {
console.error(e);
})
} else {
console.log('Service Worker is not supported in this browser.');
}
在上面的代码中,./ ./service-worker.js
是Service Worker的路径。 范围是服务工作者将采取的行动路径。 在此示例中,服务人员将控制路径为/about/
的页面。 scope
是可选的,默认情况下具有./
。 register
方法返回一个promise 。 我们可以根据需要多次调用register
方法。 完成此操作后,浏览器将自动确定它是否已经注册,并且仅在之前未注册的情况下才注册。
您可以转到chrome://serviceworker-internals
查看所有注册的服务人员。
安装
在服务工作者中,我们可以为浏览器触发的各种事件注册事件侦听器。 当浏览器首次看到Service Worker时,将触发安装事件。 当您打开Chrome的开发人员工具时,由于Service Worker在完全不同的线程中运行,因此您将看不到日志。 我们将在本教程的后面部分中讨论有关调试的更多信息。
self.addEventListener('install', function(event){
console.log(event);
});
self.addEventListener('activate', function(event){
console.log(event);
});
至此,我们将拦截对服务器的请求。 为此,我们使用self.addEventListener
方法监听'fetch'
事件,该方法在回调中返回event
对象。 我们获得请求URL作为event.request.url
的值。
self.addEventListener('fetch', function(event){
console.log(event.request.url);
// return something for each interception
});
如果要在Service Worker中导入任何外部脚本,则可以使用importScripts()
。 在本示例中,由于对cache
的支持有限,因此我们将使用cache-polyfill 。
importScripts('js/cache-polyfill.js');
var CACHE_VERSION = 'app-v1';
var CACHE_FILES = [
'/',
'images/background.jpeg',
'js/app.js',
'css/styles.css',
'https://fonts.googleapis.com/css?family=Roboto:100'
];
self.addEventListener('install', function (event) {
event.waitUntil(
caches.open(CACHE_VERSION)
.then(function (cache) {
console.log('Opened cache');
return cache.addAll(CACHE_FILES);
})
);
});
在我们的install
事件侦听器中,我们使用提供的event
对象中的waitUntil()
方法来告知浏览器服务承诺在Service Worker中的安装过程何时完成。 提供的promise是caches.open()
方法的返回值,该方法打开名为“ app-v1”的缓存。
缓存正确打开后,我们将资产添加到其中。 保存资产后, install
方法才完成。 如果保存任何一项资产时出错,则不会成功注册Service Worker。 这意味着我们应该确保只缓存重要文件,因为更多文件会增加失败的可能性。 您只应缓存可改善网页加载时间的组件。
安装步骤完成后,服务人员将激活。 这是Service Worker控制页面的地方。
现在,请求已被拦截,但是一旦发生,我们需要弄清楚我们将要做什么。 在某些情况下,Service Worker无法从缓存中读取数据,或者请求与缓存中保存的资产的请求URL不匹配。
拦截请求后,我们将执行以下操作:
- 首先,我们打开缓存并将请求与缓存中存在的请求进行匹配。 如果它们匹配,我们从缓存中返回数据。 如果请求不匹配,我们会将请求重定向到服务器。
- 从服务器成功接收到数据后,我们将返回该数据。
- 然后,我们打开缓存并使用
cache.put()
将数据保存在此处,以便在随后的尝试中可以直接从缓存中访问它们。
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).then(function(res){
if(res){
return res;
}
requestBackend(event);
})
)
});
function requestBackend(event){
var url = event.request.clone();
return fetch(url).then(function(res){
//if not a valid response send the error
if(!res || res.status !== 200 || res.type !== 'basic'){
return res;
}
var response = res.clone();
caches.open(CACHE_VERSION).then(function(cache){
cache.put(event.request, response);
});
return res;
})
}
现在,让我们分析一个需要更新缓存的场景,这很常见,因为每次更改文件都是必要的。 更改文件后,您需要在缓存中进行更新。 这是我们必须继续的方法:
- 更新
CACHE_VERSION
因为如果浏览器在Service Worker中检测到任何更改,它将重新下载它。 新服务人员中的install
事件将被触发,但新服务人员将进入“等待”阶段,因为页面仍将由旧服务人员控制。 - 当网站的所有实例关闭时,新的Service Worker将控制(而不是旧的)。
- 此时将触发
install
事件,在这里我们需要进行一些缓存管理。
我们将找到与当前版本不同的所有键,然后使用下面的函数来清理它们。
self.addEventListener('activate', function (event) {
event.waitUntil(
caches.keys().then(function(keys){
return Promise.all(keys.map(function(key, i){
if(key !== CACHE_VERSION){
return caches.delete(keys[i]);
}
}))
})
)
});
首次访问该网站时,将安装ServiceWorkers。 不要指望他们在第一次访问时就能控制该页面。 他们将只注册并安装。 该请求将转到服务器,并且将从那里获取资产。 而且,与此同时,它们将被保存在缓存中。 在以后的访问中,服务工作者将拦截请求并从缓存中返回资产。
为了更好地理解所有这些,请在开发人员工具中打开“网络”标签。 如果稍后重新打开该页面,您将看到所有缓存的资产都已从Service Worker中获取。
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
要记住的一件事是,浏览器控制着Service Worker的生存期。 安装后的运行时间不确定。
调试
对于初学者来说,Service Worker的调试有些棘手。 您必须启用它,因为它仍是一个实验。 为此,请按照下列步骤操作:
- 转到
chrome://flags
并启用“启用DevTools实验”选项。 - 打开DevTools,然后转到“设置”>“实验”,然后按Shift键6次。
- 检查“资源面板中的服务人员”,然后重新启动DevTools
现在,您已启用此实验,并且可以在DevTools的资源选项卡中找到该选项。
如果要手动注销服务工作者,请转到chrome://serviceworker-internals/
,然后单击相应的“注销”按钮。 在这里可以找到有关调试过程的更多见解 。
结论
在本文中,我们创建了一个网站,该网站演示了如何使用Service Workers创建脱机Web应用程序。 我们还讨论了有关服务工作者及其调试方法的一些概念。
我真的希望您喜欢本教程。
如果您想使用源代码,可以在这里找到 。
翻译自: https://www.sitepoint.com/getting-started-with-service-workers/
算法入门 从入门