Chrome扩展程序:在内容脚本中访问localStorage


157

我有一个选项页面,用户可以在其中定义某些选项,并将其保存在localStorage中: options.html

现在,我还有一个内容脚本,需要获取options.html页面中定义的选项,但是当我尝试从内容脚本访问localStorage时,它不会从选项页面返回值。

如何使我的内容脚本从localStorage,选项页面甚至后台页面获取值?




Answers:


233

2016年更新:

Google Chrome浏览器发布了存储API:http : //developer.chrome.com/extensions/storage.html

与其他Chrome API一样,它非常易于使用,并且您可以在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);
    });

要使用它,请确保在清单中定义它:

    "permissions": [
      "storage"
    ],

有一些方法可以“删除”,“清除”,“ getBytesInUse”和事件侦听器,以侦听更改的存储“ onChanged”

使用本地localStorage(2011年的旧答复

内容脚本在网页而不是扩展页面的上下文中运行。因此,如果您要从内容脚本访问localStorage,它将是该网页的存储空间,而不是扩展页面的存储空间。

现在,要让您的内容脚本读取扩展存储(在选项页面中进行设置),您需要使用扩展消息传递

您要做的第一件事是告诉您的内容脚本向扩展发送请求以获取一些数据,并且该数据可以作为扩展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.
});

您可以围绕该API进行操作,以将通用的localStorage数据获取到内容脚本中,或者获取整个localStorage阵列。

我希望这有助于解决您的问题。

花哨和通用...

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

1
显然,请求也可以是{method:'getStorage',key:'status'},并且侦听器将使用相应的数据进行响应。
伊纳西奥

如果我希望将localStorage中的所有内容都转移到扩展中怎么办?我可以写sendResponse({data: localStorage});吗?
Bibhas Debnath

我有点困惑。我希望我的选项页面中的数据可以在background.html页面上使用。所以我要从Background页面向内容脚本发出请求?和contentscript可以发回localStorage数据吗?看到此-> pastebin.com/xtFexFtc ..我正确吗?
Bibhas Debnath 2011年

7
后台页面和选项页面属于同一扩展上下文,因此您不需要内容脚本或消息传递。您可以localStorage直接从选项页面拨打电话,也可以从选项页面使用chrome.extension.getBackgroundPage
Mohamed Mansour

1
那很奇怪。我在选项页面中设置了几个选项,并在后台页面中基于它们创建了上下文菜单。关键是,如果我在选项页面的localStorage中设置了一个变量,除非我禁用并重新启用扩展名,否则它不会立即反映到后台页面(即没有新的上下文菜单)。您能想到什么原因?
Bibhas Debnath 2011年

47

有时,最好使用chrome.storage API。比localStorage更好,因为您可以:

  • 存储内容脚本中的信息,而无需在内容脚本和扩展名之间传递消息
  • 将数据存储为JavaScript对象,而无需将其序列化为JSON(localStorage仅存储字符串)。

这是一个演示chrome.storage用法的简单代码。内容脚本获取访问页面的URL和时间戳并存储它,popup.js从存储区域获取它。

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

这里的“更改”是一个对象,其中包含给定键的旧值和新值。“ AreaName”参数是指存储区域的名称,可以是“本地”,“同步”或“托管”。

请记住在manifest.json中声明存储权限。

manifest.json

...
"permissions": [
    "storage"
 ],
...

onChanged事件已经提供了changes对象中的数据。此外,请特别注意namespaceonChanged事件。如果您使用来存储内容chrome.storage.local.set,则会onChanged触发该事件,但是使用chrome.storage.sync.get进行读取就没有意义了。
罗布W

是的,您是对的,编辑了我的答案。显然,您可以在其他情况下使用chrome.storage.sync.get,但这确实是多余的。
Pawel Miech 2014年

针对您的答案的修订版5:changes.visitedPages如果visitedPages未更改,则将为undefined 。将生产线包起来if (changes.visitedPages) { ... }以解决此问题。
罗布W

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.