从服务工作者访问LocalStorage

发布于 2025-02-09 17:32:17 字数 270 浏览 2 评论 0 原文

我想定期调用我的服务工作者的API,以发送存储在 localstorage 的数据。当用户浏览我的网站时,将在 localstorage 中生成并保存此数据。考虑一下它之类的东西,例如在 localstorage 中保存统计信息,并通过服务工作者定期发送。我应该怎么做?我了解我无法从服务工作者访问 localstorage ,并且必须使用 postmessage api。任何帮助将不胜感激。

I want to periodically call an API from my service worker to send data stored in the localStorage. This data will be produced and saved in localStorage when a user browses my website. Consider it something like saving stats in localStorage and sending it periodically through the service worker. How should I do this? I understand that I can't access localStorage from the service worker and will have to use the postMessage API. Any help would be highly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

聚集的泪 2025-02-16 17:32:17

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

您需要使用 postmessage()回到工人的原始代码,并将该代码存储在LocalStorage中。

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

更多信息:

worker.postmessage()

https://developer.mozilla.org/en/docs/web/api/window/localstorage“ rel =“ noreferrer”> window.localstorage

pseudo code 下面的伪代码,希望您开始:

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

You cannot access localStorage (and also sessionStorage) from a webworker process, they result will be undefined, this is for security reasons.

You need to use postMessage() back to the Worker's originating code, and have that code store the data in localStorage.

You should use localStorage.setItem() and localStorage.getItem() to save and get data from local storage.

More info:

Worker.postMessage()

Window.localStorage

Pseudo code below, hoping it gets you started:

 // 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)
终止放荡 2025-02-16 17:32:17

广播频道API更容易

几种方式和控制服务工作者,但 localstorage 不是其中之一。
indexeddb 是,,但这可能是PWA的过度杀伤,一定要保持纤细。

最重要的是,“ noreferrer”>广播频道API 最容易的结果。与上述 postmessage()一起使用 MessageChannel API

这是广播的工作方式

定义了服务工作者和客户的新广播频道。

const channel4Broadcast = new BroadcastChannel('channel4');

发送在工人或客户端中发送的广播消息:

channel4Broadcast.postMessage({key: value});

接收在工人或客户端中的广播消息:

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

Broadcast Channel API is easier

There are several ways to communicate between the client and the controlling service worker, but localStorage is not one of them.
IndexedDB is, but this might be an overkill for a PWA that by all means should remain slim.

Of all means, the Broadcast Channel API results the easiest. It is by far much easier to implement than above-mentioned postMessage() with the MessageChannel API.

Here is how broadcasting works

Define a new broadcasting channel in both the service worker and the client.

const channel4Broadcast = new BroadcastChannel('channel4');

To send a broadcast message in either the worker or the client:

channel4Broadcast.postMessage({key: value});

To receive a broadcast message in either the worker or the client:

channel4Broadcast.onmessage = (event) => {
    value = event.data.key;
}
满身野味 2025-02-16 17:32:17

我一直在使用此软件包,称为 localforage ,它提供了一个localstorage的接口,该接口包裹在索引中。 https://github.com/localforage/localforage/localforage

然后,您可以通过将其放置在您的公共目录中来导入它,因此由您的Web服务器提供服务,然后致电: self.importscripts('localforage.js'); 在您的服务工作者中。

I've been using this package called localforage that provides a localStorage-like interface that wraps around IndexedDB. https://github.com/localForage/localForage

You can then import it by placing it in your public directory, so it is served by your webserver, and then calling: self.importScripts('localforage.js'); within your service worker.

薆情海 2025-02-16 17:32:17

注意:LocalStorage的工作方式与服务工作者缓存类似,但它是同步的,因此不允许在服务工作人员中。

注意:如果您需要,则可以在服务工作者内使用索引。

另外,这里还有一些讨论:如何使用Angular的服务工作人员访问本地存储?

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

Note: localStorage works in a similar way to service worker cache, but it is synchronous, so not allowed in service workers.

Note: IndexedDB can be used inside a service worker for data storage if you require it.

Also there is a bit of discussion here: How do I access the local storage using service workers in angular?

面如桃花 2025-02-16 17:32:17

我本人绊倒这个问题是一个很小的WebApp项目,我考虑了以下解决方案:
当用户在线时,可以立即发送数据。当他离线时,我使用 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 一旦用户上网,就将新值保存到后端。
这不会使服务人员访问LocalStorage,但会给他带来每一个更改。

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

Stumbling over this question myself for a tiny webapp-project, I considered the following solution:
When the user is online, the data can be sent immediately. When he is offline, I use the SyncEvent.tag property to send information from the client to the serviceworker. Like this:

//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 saves the new value to backend, as soon as the user goes online.
This won't give the service worker access to the localStorage, but it will send him every change made.

Just starting to get used to this syncing topic. So I would really be interested, wheather this is helpful and what others think about this solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文