Service Worker的学习
限制:只有在https协议下 Service Worker 才能够被注册,本地调试可用localhost。
Service Worker 的生命周期
一、注册service worker
if (navigator.serviceWorker) { // 判断是否支持service worker
// 注册service worker
navigator.serviceWorker.register('./service-worker.js', // service worker 配置文件的位置
{
scope: './' // 作用域为当前目录
}).then(function (reg) {
console.log(reg);
}).catch(function (e) {
console.log(e);
})
} else {
alert('Service Worker is not supported!');
}
二、缓存文件 的配置
// service-worker.js
self.addEventListener('install', function (e) {
e.waitUntil(
caches.open('app-v1') // 打开缓存
.then(function (cache) {
console.log('open cache')
return cache.addAll([ // 缓存所有不需要经常更新的文件
'./app.js',
'./main.css',
'./serviceWorker.html'
])
})
)
})
三、拦截请求 的配置
// service-worker.js
self.addEventListener('fetch', function (e) {
e.respondWith(
caches.match(e.request).then(function (res) { // 先在cacheStorage中寻找资源
if (res) { // 若cacheStorage中有缓存资源,则直接返回资源
return res
} else { // 若cacheStorage中无匹配的缓存资源,则向网络发起请求
// 通过fetch方法去先网络发起请求
fetch(资源uri).then(function (res) {
if (res) {
对于新请求到的资源存储到cacheStorage中
} else {
提供用户提示
}
})
}
})
)
})
四、页面通信 的配置
通过 navigator.serviceWorker.controller.postMessage()
来通信
eg:
<!--msg-demo.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>msg-demo</title>
</head>
<body>
<ul id="msg-box">
</ul>
<input type="text" id="msg-input" />
<button id="send-msg-button">发送</button>
<script src="./msgapp.js"></script>
</body>
</html>
// msgapp.js
if (navigator.serviceWorker) {
var sendBtn = document.getElementById('send-msg-button'); // 获取button元素
var msgInput = document.getElementById('msg-input'); // 获取input框元素
var msgBox = document.getElementById('msg-box'); // 获取ul列表元素
// 监听数据的接收
navigator.serviceWorker.addEventListener('message', function (event) {
// 当从serviceWorker获取到数据的时候,就显示在页面上
msgBox.innerHTML = msgBox.innerHTML + ('<li>' + event.data.message + '</li>');
})
// 点击发送按钮发送input框中的内容给serviceWorker
sendBtn.addEventListener('click', function () {
// 主页面发送信息到serviceWorker,navigator.serviceWorker.controller在serviceWorker未注册成功前为空
navigator.serviceWorker.controller.postMessage(msgInput.value);
})
// 注册serviceWorker
navigator.serviceWorker.register('./msgsw.js', // service worker 配置文件的位置
{
scope: './' // 作用域为当前目录
}).then(function (reg) {
console.log(reg);
}).catch(function (e) {
console.log(e);
})
} else {
alert('Service Worker is not supported!');
}
// msgsw.js
// serviceWorker监听数据的接收
self.addEventListener('message', function (event) {
// 接收到数据后广播到除了发送源以外的所有客户端
// self.clients.matchAll() 匹配所有这个serviceWorker下的客户端
var promise = self.clients.matchAll().then(function (clientList) {
// 获取发送源的唯一标志ID
var senderID = event.source ? event.source.id : 'unknown'
clientList.forEach(function (client) {
if (client.id === senderID) { // 当客户端ID===发送源ID,则不serviceWorker发送数据到页面
return
} else {
// 向其他页面发送数据
client.postMessage({
client: senderID,
message: event.data
})
}
})
})
event.waitUntil(promise) // waitUntil等待一个promise事件
})