Extension Chrome: accéder à localStorage dans le script de contenu

157

J'ai une page d'options où l'utilisateur peut définir certaines options et il l'enregistre dans localStorage: options.html

Maintenant, j'ai également un script de contenu qui doit obtenir les options définies dans la options.htmlpage, mais lorsque j'essaie d'accéder à localStorage à partir du script de contenu, il ne renvoie pas la valeur de la page d'options.

Comment faire en sorte que mon script de contenu obtienne des valeurs de localStorage, de la page d'options ou même de la page d'arrière-plan?

user476214
la source

Réponses:

233

Mise à jour 2016:

Google Chrome a publié l'API de stockage: http://developer.chrome.com/extensions/storage.html

Il est assez facile à utiliser comme les autres API Chrome et vous pouvez l'utiliser à partir de n'importe quel contexte de page dans Chrome.

    // Save it using the Chrome extension storage API.
    chrome.storage.sync.set({'foo': 'hello', 'bar': 'hi'}, function() {
      console.log('Settings saved');
    });

    // Read it using the storage API
    chrome.storage.sync.get(['foo', 'bar'], function(items) {
      message('Settings retrieved', items);
    });

Pour l'utiliser, assurez-vous de le définir dans le manifeste:

    "permissions": [
      "storage"
    ],

Il existe des méthodes pour "supprimer", "effacer", "getBytesInUse" et un écouteur d'événements pour écouter le stockage modifié "onChanged"

Utilisation de localStorage natif ( ancienne réponse de 2011 )

Les scripts de contenu s'exécutent dans le contexte de pages Web, pas de pages d'extension. Par conséquent, si vous accédez à localStorage à partir de votre contentscript, ce sera le stockage de cette page Web, pas le stockage de la page d'extension.

Maintenant, pour permettre à votre script de contenu de lire votre stockage d'extension (où vous les définissez à partir de votre page d'options), vous devez utiliser la transmission de message d' extension .

La première chose que vous faites est de dire à votre script de contenu d'envoyer une requête à votre extension pour récupérer des données, et ces données peuvent être votre extension localStorage:

contentscript.js

chrome.runtime.sendMessage({method: "getStatus"}, function(response) {
  console.log(response.status);
});

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.method == "getStatus")
      sendResponse({status: localStorage['status']});
    else
      sendResponse({}); // snub them.
});

Vous pouvez faire une API autour de cela pour obtenir des données génériques localStorage dans votre script de contenu, ou peut-être, obtenir l'ensemble du tableau localStorage.

J'espère que cela a aidé à résoudre votre problème.

Pour être sophistiqué et générique ...

contentscript.js

chrome.runtime.sendMessage({method: "getLocalStorage", key: "status"}, function(response) {
  console.log(response.data);
});

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.method == "getLocalStorage")
      sendResponse({data: localStorage[request.key]});
    else
      sendResponse({}); // snub them.
});
Mohamed Mansour
la source
1
Évidemment, la requête pourrait aussi être {method: 'getStorage', key: 'status'}, et l'auditeur répondrait avec les données correspondantes.
JC Inacio
Que faire si je souhaite que tout ce qui se trouve depuis localStorage soit transféré vers l'extension? Puis-je écrire sendResponse({data: localStorage});?
Bibhas Debnath
Je suis un peu confus. Je veux que les données de ma page d'options soient disponibles sur la page background.html .. Donc je fais une demande de la page Background au contentscript? et contentscript peut renvoyer les données localStorage? Voir ceci -> pastebin.com/xtFexFtc .. Est-ce que je le fais correctement?
Bibhas Debnath
7
La page d'arrière-plan et la page d'options appartiennent au même contexte d'extension, vous n'avez donc pas besoin de scripts de contenu ou de messagerie. Vous pouvez appeler localStoragedirectement à partir de la page d'options ou utiliser à chrome.extension.getBackgroundPagepartir de la page d'options.
Mohamed Mansour
1
C'est étrange. Je mets quelques options dans la page d'options et crée des menus contextuels basés sur eux dans la page d'arrière-plan. Le fait est que si je place une variable dans localStorage à partir de la page d'options, elle ne se reflète pas immédiatement sur la page d'arrière-plan (c'est-à-dire pas de nouveau menu contextuel), sauf si je désactive et réactive l'extension. Une raison à laquelle vous pouvez penser?
Bibhas Debnath
47

Parfois, il peut être préférable d'utiliser l' API chrome.storage . C'est mieux que localStorage car vous pouvez:

  • stocker les informations de votre script de contenu sans avoir besoin de passer un message entre le script de contenu et l'extension;
  • stockez vos données en tant qu'objets JavaScript sans les sérialiser en JSON ( localStorage ne stocke que des chaînes ).

Voici un code simple démontrant l'utilisation de chrome.storage. Le script de contenu obtient l'URL de la page visitée et l'horodatage et le stocke, popup.js l'obtient à partir de la zone de stockage.

content_script.js

(function () {
    var visited = window.location.href;
    var time = +new Date();
    chrome.storage.sync.set({'visitedPages':{pageUrl:visited,time:time}}, function () {
        console.log("Just visited",visited)
    });
})();

popup.js

(function () {
    chrome.storage.onChanged.addListener(function (changes,areaName) {
        console.log("New item in storage",changes.visitedPages.newValue);
    })
})();

"Modifications" ici est un objet qui contient l'ancienne et la nouvelle valeur pour une clé donnée. L'argument "AreaName" fait référence au nom de la zone de stockage, soit "local", "sync" ou "géré".

N'oubliez pas de déclarer l'autorisation de stockage dans manifest.json.

manifest.json

...
"permissions": [
    "storage"
 ],
...
Pawel Miech
la source
L' onChangedévénement fournit déjà les données dans l' changesobjet. De plus, portez une attention particulière à namespacel' onChangedévénement. Si vous stockez quelque chose en utilisant chrome.storage.local.set, l' onChangedévénement est déclenché, mais la lecture en utilisant chrome.storage.sync.getn'a pas de sens.
Rob W
Oui, tu as raison, a édité ma réponse. Évidemment, vous pouvez utiliser chrome.storage.sync.get dans d'autres scénarios, mais ici c'est effectivement redondant.
Pawel Miech
En réponse à la révision 5 de votre réponse: changes.visitedPagessera indéfini si visitedPagesn'a pas été modifié. Enveloppez la ligne if (changes.visitedPages) { ... }pour résoudre ce problème.
Rob W
7

Une autre option serait d'utiliser l'API chromestorage. Cela permet le stockage des données utilisateur avec une synchronisation facultative entre les sessions.

Un inconvénient est qu'il est asynchrone.

https://developer.chrome.com/extensions/storage.html

Jason
la source
@Jason, qu'en est-il des transactions tout ou rien ?
Pacerier