【问题标题】:Chrome extension: accessing localStorage in content scriptChrome 扩展:在内容脚本中访问 localStorage
【发布时间】:2011-04-25 14:51:48
【问题描述】:

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

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

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

【问题讨论】:

标签: google-chrome-extension local-storage content-script


【解决方案1】:

2016 年更新:

谷歌浏览器发布存储API:https://developer.chrome.com/docs/extensions/reference/storage/

与其他 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"
    ],

有“remove”、“clear”、“getBytesInUse”和一个事件监听器来监听改变的存储“onChanged”

使用原生 localStorage(2011 年的旧回复

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

现在,要让您的内容脚本读取您的扩展存储(您在选项页面中设置它们的位置),您需要使用扩展 message passing

您要做的第一件事是告诉您的内容脚本向您的扩展发送请求以获取一些数据,而该数据可以是您的扩展本地存储:

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

【讨论】:

  • 显然request也可以是{method:'getStorage', key: 'status'},监听器会响应相应的数据。
  • 如果我希望将 localStorage 中的所有内容转移到扩展程序中怎么办?我可以写sendResponse({data: localStorage}); 吗?
  • 我有点困惑。我希望我的选项页面中的数据在 background.html 页面上可用。所以我从背景页面向 contentscript 发出请求?和 contentscript 可以发回 localStorage 数据?看到这个 -> pastebin.com/xtFexFtc .. 我做对了吗?
  • 后台页面和选项页面属于同一个扩展上下文,所以你不需要内容脚本或消息传递。您可以直接从选项页面调用localStorage,也可以从选项页面使用chrome.extension.getBackgroundPage
  • 这很奇怪。我在选项页面中设置了几个选项,并在后台页面中基于它们创建上下文菜单。问题是,如果我从选项页面在 localStorage 中设置一个变量,它不会立即反映到后台页面(即没有新的上下文菜单),除非我禁用并重新启用扩展。你能想到什么理由?
【解决方案2】:

另一种选择是使用 chromestorage API。这允许通过可选的跨会话同步来存储用户数据。

一个缺点是它是异步的。

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

【讨论】:

  • @Jason,全有或全无的事务怎么样?
【解决方案3】:

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

  • 存储内容脚本中的信息无需 内容脚本和扩展之间的消息传递
  • 将您的数据存储为 JavaScript 对象,无需将它们序列化为 JSON (localStorage only stores strings)。

这是一个演示 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);
    })
})();

这里的“Changes”是一个包含给定键的旧值和新值的对象。 “AreaName”参数是指存储区域的名称,可以是“local”、“sync”或“managed”。

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

ma​​nifest.json

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

【讨论】:

  • onChanged 事件已经提供了changes 对象中的数据。此外,请特别注意onChanged 事件的namespace。如果您使用chrome.storage.local.set 存储内容,则触发onChanged 事件,但使用chrome.storage.sync.get 读取没有什么意义。
  • 是的,你是对的,编辑了我的答案。显然你可以在其他场景中使用 chrome.storage.sync.get,但是这里确实是多余的。
  • 响应您答案的修订版 5:如果 visitedPages 未更改,changes.visitedPages 将未定义。在if (changes.visitedPages) { ... } 中换行来解决这个问题。
猜你喜欢
  • 1970-01-01
  • 2011-04-25
  • 2016-11-19
  • 2012-07-04
  • 2013-05-20
  • 1970-01-01
相关资源
最近更新 更多