Come gestire correttamente gli aggiornamenti delle estensioni di Chrome dagli script di contenuto

Nella pagina di sfondo siamo in grado di rilevare gli aggiornamenti delle estensioni utilizzando chrome.runtime.onInstalled.addListener .

Ma dopo che l’estensione è stata aggiornata, tutti gli script di contenuto non possono connettersi alla pagina di sfondo. E otteniamo un errore: Error connecting to extension ....

È ansible re-iniettare script di contenuto usando chrome.tabs.executeScript … Ma cosa succede se abbiamo dati sensibili che dovrebbero essere salvati prima di un aggiornamento e usati dopo l’aggiornamento? Cosa potremmo fare?

Inoltre, se re-iniettiamo tutti gli script di contenuto, dovremmo abbattere correttamente gli script di contenuto precedenti.

Qual è il modo corretto di gestire gli aggiornamenti delle estensioni dagli script di contenuto senza perdere i dati dell’utente?

Una volta che l’aggiornamento dell’estensione di Chrome si verifica, lo script di contenuto “orfano” è completamente escluso dall’estensione. L’unico modo in cui può ancora comunicare è tramite DOM condiviso. Se stai parlando di dati veramente sensibili, questo non è sicuro dalla pagina. Maggiori informazioni in seguito.

Innanzitutto, è ansible ritardare un aggiornamento. Nel tuo script in background, aggiungi un gestore per l’evento chrome.runtime.onUpdateAvailable . Finché l’ascoltatore è lì, hai la possibilità di fare pulizia.

 // Background script chrome.runtime.onUpdateAvailable.addListener(function(details) { // Do your work, call the callback when done syncRemainingData(function() { chrome.runtime.reload(); }); }); 

Secondo, supponiamo che il peggio accada e che tu sia tagliato fuori. Puoi ancora comunicare usando gli eventi DOM:

 // Content script // Get ready for data window.addEventListener("SendRemainingData", function(evt) { processData(evt.detail); }, false); // Request data var event = new CustomEvent("RequestRemainingData"); window.dispatchEvent(event); // Be ready to send data if asked later window.addEventListener("RequestRemainingData", function(evt) { var event = new CustomEvent("SendRemainingData", {detail: data}); window.dispatchEvent(event); }, false); 

Tuttavia, questo canale di comunicazione è potenzialmente intercettato dalla pagina host. E, come detto in precedenza, l’intercettazione non è qualcosa che puoi bypassare.

Tuttavia, puoi avere dati pre-condivisi fuori banda. Supponiamo di generare una chiave casuale alla prima installazione e di mantenerla in chrome.storage – questo non è accessibile dalle pagine web con qualsiasi mezzo. Certo, una volta orfano non puoi leggerlo, ma puoi farlo al momento dell’iniezione.

 var PSK; chrome.storage.local.get("preSharedKey", function(data) { PSK = data.preSharedKey; // ... window.addEventListener("SendRemainingData", function(evt) { processData(decrypt(evt.detail, PSK)); }, false); // ... window.addEventListener("RequestRemainingData", function(evt) { var event = new CustomEvent("SendRemainingData", {detail: encrypt(data, PSK)}); window.dispatchEvent(event); }, false); }); 

Questo è ovviamente il codice di proof-of-concept. Dubito che avrai bisogno di più di un ascoltatore onUpdateAvailable .

Se hai stabilito una comunicazione tramite var port = chrome.runtime.connect(...) (come descritto su https://developer.chrome.com/extensions/messaging#connect ), dovrebbe essere ansible ascoltare il evento runtime.Port.onDisconnect :

 tport.onDisconnect.addListener(function(msg) {...}) 

Qui puoi reactjs e, ad esempio, applicare una sorta di memoizzazione, diciamo tramite localStorage . Ma in generale, suggerirei di mantenere gli script di contenuto il più piccolo ansible ed eseguire tutte le manipolazioni di dati in background, lasciando che il contenuto raccolga / trasmetta solo i dati e ne restituisca uno stato, se necessario.