我希望定期从我的服务工作线程调用API,以发送存储在localStorage
中的数据。当用户浏览我的网站时,这些数据将被生成并保存在localStorage
中。就像在localStorage
中保存统计信息,并通过服务工作线程定期发送一样。我该怎么做?我知道我不能从服务工作线程访问localStorage
,必须使用postMessage
API。非常感谢您的帮助。
我希望定期从我的服务工作线程调用API,以发送存储在localStorage
中的数据。当用户浏览我的网站时,这些数据将被生成并保存在localStorage
中。就像在localStorage
中保存统计信息,并通过服务工作线程定期发送一样。我该怎么做?我知道我不能从服务工作线程访问localStorage
,必须使用postMessage
API。非常感谢您的帮助。
由于安全原因,无法从WebWorker进程访问localStorage(以及sessionStorage),它们的结果将为undefined
。
您需要使用postMessage()
将数据发送回工作线程的源代码,并让该代码将数据存储在localStorage中。
应使用localStorage.setItem()
和localStorage.getItem()
保存和获取本地存储中的数据。
更多信息:
下面是伪代码,希望能帮助您入门:
// include your worker
var myWorker = new Worker('YourWorker.js'),
data,
changeData = function() {
// save data to local storage
localStorage.setItem('data', (new Date).getTime().toString());
// get data from local storage
data = localStorage.getItem('data');
sendToWorker();
},
sendToWorker = function() {
// send data to your worker
myWorker.postMessage({
data: data
});
};
setInterval(changeData, 1000)
var myWorker = new YourWorker('YourWorker.js'),
> new WebWorker
对吗? - roberrrt-slocalStorage
与安全有关?Service workers的MDN页面只提到同步性,但甚至没有支持这一点。 - AntonOfTheWoods有几种方法可以在客户端和控制服务工作者之间通信,但是localStorage
不是其中之一。IndexedDB
是一种方法,但这可能会使PWA变得过于臃肿。
在所有方法中,Broadcast Channel API 是最容易的。它比上述使用MessageChannel API
的postMessage()
实现要容易得多。
在服务工作者和客户端中都定义一个新的广播频道。
const channel4Broadcast = new BroadcastChannel('channel4');
在 worker 或 client 中发送广播消息的方法:
channel4Broadcast.postMessage({key: value});
要在 worker 或 client 中接收广播消息:
channel4Broadcast.onmessage = (event) => {
value = event.data.key;
}
channel4Broadcast.onmessage
被初始化吗? - undefined我一直在使用一个叫做localforage
的包,它提供了类似于localStorage的接口,封装了IndexedDB。https://github.com/localForage/localForage
然后你可以通过将它放置在公共目录中,并由Web服务器提供服务,然后在你的Service Worker中调用:self.importScripts('localforage.js');
来导入它。
https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_API/Using_Service_Workers 上说:
注意:localStorage 与 service worker 缓存的工作方式类似,但它是同步的,因此不允许在 service worker 中使用。
注意:如果需要,可以在 service worker 中使用 IndexedDB 进行数据存储。
此外,这里还有一些讨论:如何在 Angular 中使用 service worker 访问本地存储?
SyncEvent.tag
属性将信息从客户端发送到serviceworker。就像这样:
//offline_page.html (loads only, when user is offline)
button.onclick = function() {
//on click: store new value in localStorage and prepare new value for synchronization
localStorage.setItem("actual", numberField.value);
navigator.serviceWorker.ready.then(function(swRegistration) {
return swRegistration.sync.register('newval:'+numberField.value);
});
}
//sw.js
self.addEventListener('sync', function(event) {
//let's say everything in front of ':' is the option, everything afterwards is the value
let option = event.tag.replace(/(.*?)\:.*?$/, "$1");
let value = event.tag.replace(/.*?\:(.*?)$/, "$1");
if(option == "newval") {
event.waitUntil(
fetch("update.php?newval="+value)
.then(function(response) {
console.log(response);
})
);
}
});
update.php
会在用户上线时将新值保存到后端,但这不会给服务工作者访问本地存储的权限,但它会将每个变更发送给服务工作者。
刚开始逐渐了解这个同步主题。所以我非常感兴趣,这是否有帮助,以及其他人对此解决方案的看法。