从服务工作者访问localStorage

时间:2016-11-30 11:49:00

标签: javascript html5 service-worker web-worker

我想定期从我的服务工作者调用API来发送存储在localStorage中的数据。当用户浏览我的网站时,将生成此数据并将其保存在localStorage中。考虑一下像在localStorage中保存统计信息并定期通过服务工作者发送它。我该怎么做?我知道我无法从服务工作者访问localStorage,并且必须使用postMessage API。任何帮助都将受到高度赞赏。

5 个答案:

答案 0 :(得分:8)

您无法从webworker进程访问localStorage(以及sessionStorage),结果将是undefined,这是出于安全原因。

您需要使用postMessage()回到Worker的原始代码,并让该代码将数据存储在localStorage中。

您应该使用localStorage.setItem()localStorage.getItem()来保存并从本地存储中获取数据。

更多信息:

Worker.postMessage()

Window.localStorage

下面的伪代码,希望它能帮到你:

 // 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)

答案 1 :(得分:2)

我一直在使用名为localforage的程序包,该程序包提供了一个类似于LocalStorage的接口,该接口包装了IndexedDB。 https://github.com/localForage/localForage

然后可以通过将其放置在公共目录中来导入它,以便由Web服务器为其提供服务,然后在服务工作者中调用:self.importScripts('localforage.js');

答案 2 :(得分:1)

我自己为一个小型的Webapp项目遇到了这个问题,我考虑了以下解决方案: 当用户在线时,可以立即发送数据。当他离线时,我使用SyncEvent.tag属性将信息从客户端发送到服务工作人员。像这样:

//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会将新值保存到后端。 这不会使服务人员可以访问localStorage,但会将所做的所有更改发送给他。

刚刚开始习惯这个同步主题。因此,我真的很感兴趣,这对您有所帮助,以及其他人对此解决方案的看法。

答案 3 :(得分:0)

https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers

  

注意:localStorage的工作方式与服务工作者缓存类似,但是它是同步的,因此服务工作者中不允许这样做。

     

注意:如果需要,可以在Service Worker中使用IndexedDB进行数据存储。

这里也有一些讨论:How do I access the local storage using service workers in angular?

答案 4 :(得分:0)

广播频道 API 更简单

several ways 用于在客户端和控制 Service Worker 之间进行通信,但 localStorage 不是其中之一。 IndexedDB 是,,但这对于无论如何都应该保持苗条的 PWA 来说可能是一种矫枉过正。

总之,Broadcast Channel API 的结果最简单。到目前为止,使用 MessageChannel API 实现比上述 postMessage() 容易得多。

广播的工作原理

在 Service Worker 和客户端中定义一个新的广播频道。

const channel4Broadcast = new BroadcastChannel('channel4');

要在工作程序或客户端中发送广播消息:

channel4Broadcast.postMessage({key: value});

要在工作程序或客户端接收广播消息:

channel4Broadcast.onmessage = (event) => {
    value = event.data.key;
}