Каковы ограничения на использование работника службы для хранения переменной javascript между перезагрузками страницы? - PullRequest
0 голосов
/ 17 сентября 2018

С помощью двунаправленных каналов сервисных работников (MessageChannel / postMessage) можно «сохранить» значение переменной javascript в глобальной области видимости сервисного работника между перезагрузками страниц, навигацией, нажатиями кнопок назад / вперед (это также работает черезвкладки, но мне все равно):

//query data
send_message_to_sw("").then(function(response) {
    var data;
    if (response) {
        //restore data
        data = response;
    } else {
        data = confirm("the button you choose will be remembered for some time, but sometimes you'll have to click again") ? "left" : "right";
        //Store data
        send_message_to_sw(data)
    }
    alert("data: " + data);
    return data;
 });

Хотя срок службы сервисных работников должен быть очень коротким и его глобальная область действия часто сбрасывается, в Firefox 61 я вижу, что глобальный масштаб работника сервисной службы сохраняет данные нетронутыми (полный код доступен в конце вопроса).

Вопросы:

1) Есть ли способ гарантировать, что глобальная область работника службы не будет сброшена?Работник службы ничего не делает, но хранит несколько сотен байтов в своей глобальной области (без продолжительных вычислений, без извлечения, без зависания).

2) Для перезагрузки страницы, как этот метод сравнивается с установкойзначение скрытого поля.Есть ли у него меньше или больше гарантий?И на практике, вы получаете такое же поведение?(Я думаю, что установка значения скрытого поля не сохраняется на диске, но я не уверен)

3) Каковы другие альтернативы этой технике?Я пытаюсь хранить очень конфиденциальные данные (криптографический закрытый ключ: никогда не следует записывать на диск; его можно восстановить, попросив пользователя повторно ввести свой пароль, но для удобства следует запомнить его "на некоторое время") при перезагрузке страницы илинавигация.

КОД:

app.js

function send_message_to_sw(msg){
    return new Promise(function(resolve, reject){
        // Create a Message Channel
        var msg_chan = new MessageChannel();

        // Handler for recieving message reply from service worker
        msg_chan.port1.onmessage = function(event){
            if(event.data.error){
                reject(event.data.error);
            }else{
                resolve(event.data);
            }
        };

        // Send message to service worker along with port for reply
        navigator.serviceWorker.controller.postMessage(msg, [msg_chan.port2]);
    });
}

sw.js

self.addEventListener('message', function(event){
    if (event.data !== "") {
        self.GLOBALDATA = event.data;
    }
    event.ports[0].postMessage(self.GLOBALDATA||"");
});
...