Chrome-Erweiterung: Zugriff auf localStorage im Inhaltsskript

157

Ich habe eine Optionsseite, auf der der Benutzer bestimmte Optionen definieren und in localStorage speichern kann: options.html

Jetzt habe ich auch ein Inhaltsskript, das die auf der options.htmlSeite definierten Optionen abrufen muss. Wenn ich jedoch versuche, über das Inhaltsskript auf localStorage zuzugreifen, wird der Wert von der Optionsseite nicht zurückgegeben.

Wie kann ich dafür sorgen, dass mein Inhaltsskript Werte von localStorage, von der Optionsseite oder sogar von der Hintergrundseite erhält?

user476214
quelle
1
Siehe auch
Shay Erlichmen
Siehe auch
Jason
Siehe auch
super1ha1

Antworten:

233

Update 2016:

Google Chrome hat die Speicher-API veröffentlicht: http://developer.chrome.com/extensions/storage.html

Es ist ziemlich einfach wie die anderen Chrome-APIs zu verwenden und kann von jedem Seitenkontext in Chrome aus verwendet werden.

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

Um es zu verwenden, stellen Sie sicher, dass Sie es im Manifest definieren:

    "permissions": [
      "storage"
    ],

Es gibt Methoden zum "Entfernen", "Löschen", "getBytesInUse" und einen Ereignis-Listener zum Abhören des geänderten Speichers "onChanged".

Verwenden von nativem localStorage ( alte Antwort von 2011 )

Inhaltsskripte werden im Kontext von Webseiten ausgeführt, nicht von Erweiterungsseiten. Wenn Sie über Ihr Inhaltsskript auf localStorage zugreifen, handelt es sich daher um den Speicher dieser Webseite und nicht um den Speicher der Erweiterungsseite.

Damit Ihr Inhaltsskript Ihren Erweiterungsspeicher lesen kann (wo Sie sie auf Ihrer Optionsseite festgelegt haben), müssen Sie die Weitergabe von Erweiterungsnachrichten verwenden .

Das erste, was Sie tun, ist, Ihr Inhaltsskript anzuweisen, eine Anforderung an Ihre Erweiterung zu senden, um einige Daten abzurufen. Diese Daten können Ihre Erweiterung localStorage sein:

contentcript.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.
});

Sie können eine API erstellen, um generische localStorage-Daten in Ihr Inhaltsskript abzurufen, oder möglicherweise das gesamte localStorage-Array abrufen.

Ich hoffe, das hat zur Lösung Ihres Problems beigetragen.

Ausgefallen und generisch zu sein ...

contentcript.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
quelle
1
Offensichtlich könnte die Anfrage auch {method: 'getStorage', key: 'status'} sein, und der Listener würde mit den entsprechenden Daten antworten.
JC Inacio
Was ist, wenn ich möchte, dass alles aus dem localStorage auf die Erweiterung übertragen wird? Kann ich schreiben sendResponse({data: localStorage});?
Bibhas Debnath
Ich bin ein bisschen verwirrt. Ich möchte, dass Daten von meiner Optionsseite auf der Seite background.html verfügbar sind. Also stelle ich eine Anfrage von der Hintergrundseite zum Inhaltsskript? und Inhaltsskript können die localStorage-Daten zurücksenden? Siehe dies -> pastebin.com/xtFexFtc .. Mache ich es richtig?
Bibhas Debnath
7
Die Hintergrundseite und die Optionsseite gehören zum selben Erweiterungskontext, sodass Sie keine Inhaltsskripte oder Nachrichten benötigen. Sie können localStoragedirekt von der Optionsseite aus anrufen oder chrome.extension.getBackgroundPagevon der Optionsseite aus verwenden.
Mohamed Mansour
1
Das ist seltsam. Ich setze einige Optionen auf der Optionsseite und erstelle Kontextmenüs basierend auf diesen auf der Hintergrundseite. Die Sache ist, wenn ich eine Variable in localStorage von der Optionsseite aus setze, wird sie nicht sofort auf der Hintergrundseite angezeigt (dh kein neues Kontextmenü), es sei denn, ich deaktiviere die Erweiterung und aktiviere sie erneut. Gibt es einen Grund, an den Sie denken können?
Bibhas Debnath
47

Manchmal ist es möglicherweise besser, die chrome.storage- API zu verwenden. Es ist besser als localStorage, weil Sie:

  • Speichern Sie Informationen aus Ihrem Inhaltsskript, ohne dass eine Nachricht zwischen Inhaltsskript und Erweiterung übertragen werden muss.
  • Speichern Sie Ihre Daten als JavaScript-Objekte, ohne sie in JSON zu serialisieren ( localStorage speichert nur Zeichenfolgen ).

Hier ist ein einfacher Code, der die Verwendung von chrome.storage demonstriert. Das Inhaltsskript ruft die URL der besuchten Seite und den Zeitstempel ab und speichert sie. Popup.js ruft sie aus dem Speicherbereich ab.

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);
    })
})();

"Änderungen" ist hier ein Objekt, das einen alten und einen neuen Wert für einen bestimmten Schlüssel enthält. Das Argument "AreaName" bezieht sich auf den Namen des Speicherbereichs, entweder "lokal", "synchronisieren" oder "verwaltet".

Denken Sie daran, die Speicherberechtigung in manifest.json zu deklarieren.

manifest.json

...
"permissions": [
    "storage"
 ],
...
Pawel Miech
quelle
Das onChangedEreignis liefert bereits die Daten im changesObjekt. Achten Sie außerdem besonders auf namespacedie onChangedVeranstaltung. Wenn Sie etwas mit speichern chrome.storage.local.set, wird das onChangedEreignis ausgelöst, aber das Lesen mit chrome.storage.sync.getmacht wenig Sinn.
Rob W
Ja, du hast recht, habe meine Antwort bearbeitet. Natürlich können Sie chrome.storage.sync.get in anderen Szenarien verwenden, aber hier ist es tatsächlich redundant.
Pawel Miech
Als Antwort auf Revision 5 Ihrer Antwort: changes.visitedPageswird undefiniert, wenn visitedPagessie nicht geändert wurde. Wickeln Sie die Linie ein if (changes.visitedPages) { ... }, um dieses Problem zu lösen.
Rob W
7

Eine andere Option wäre die Verwendung der Chromspeicher-API. Dies ermöglicht die Speicherung von Benutzerdaten mit optionaler Synchronisierung zwischen Sitzungen.

Ein Nachteil ist, dass es asynchron ist.

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

Jason
quelle
@ Jason, was ist mit Alles-oder-Nichts- Transaktionen ?
Pacerier