Chrome扩展程序:在后台存储数据

时间:2012-06-28 06:04:44

标签: javascript google-chrome-extension local-storage

我希望能够在后台(在我的扩展程序上)存储数据,以便我可以在多个域之间访问此数据。

我在做什么:

内容-的script.js

function setItem(name, data) {
    chrome.extension.sendMessage({ command: 'setItem', name: name, data: data });
}

function getItem(name) {
    chrome.extension.sendMessage({ command: 'getItem', name: name }, function(response) {
        return response;
    });
}

背景的script.js

Storage.prototype.setObject = function(key, value) {
    this.setItem(key, JSON.stringify(value));
}

Storage.prototype.getObject = function(key) {
    var value = this.getItem(key);
    return value && JSON.parse(value);
}

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    switch (request.command) {
        case 'setItem':
            localStorage.setObject(request.name, request.data);
            return;
        case 'getItem':
            sendResponse(localStorage.getObject(request.name));
            return;
    }
});

但没有成功,因为我无法从 getItem 的回调中返回。

我确实在function(response) { }回调中获取了数据,我无法将其作为 getItem 的返回值返回。

我该怎么做?

3 个答案:

答案 0 :(得分:9)

2012年的问题提出了最新的答案。好吧,那么..

现在正确的答案是使用chrome.storage API。它是一个可用于扩展页面和内容脚本的API,它提供异步存储。它需要"storage"权限,但此权限不会生成任何警告。

// Setting
chrome.storage.local.set({key: data}, function() {
  if(chrome.runtime.lastError) {
    console.error(
      "Error setting " + key + " to " + JSON.stringify(data) +
      ": " + chrome.runtime.lastError.message
    );
  }
});

// Getting
chrome.storage.local.get("key", function(data) {
  // Do something with data.key
});

另请参阅文档的Examples部分。

请注意,在任何一种情况下(此方法或后台消息传递方法)都无法使返回结果的函数getData,因为调用是异步的。

一些提示和技巧:

  1. 您可以通过将对象或数组作为查询传递来一次设置或获取多个值。您可以通过传递null查询来阅读所有值。

  2. 通过传递get()

  3. 之类的查询,您可以为{key: defaultValue}操作提供默认值,以防万一没有为该密钥存储值
  4. 您可以通过chrome.storage.onChanged事件通知存储的所有更改。

  5. chrome.storage.local遵守"unlimitedStorage"权限。

  6. 如果Chrome扩展程序启用了Chrome同步,
  7. chrome.storage.sync会将该值传播到登录到同一Google帐户的所有配置文件。但请记住quotas

  8. 如果您绝对需要同步访问,则可以使用chrome.storage支持的本地缓存伪造它。但是,有一些限制:在同步代码块中,您的缓存不会随着其他页面的更改而更新,您需要异步读取值以填充缓存。

答案 1 :(得分:5)

Content.js

var someVar = "hey hey!";

chrome.extension.sendRequest({method: "fromContentScript",greeting: someVar}, function(response) {

    console.log(response.data); // response back from BG

    if(response.who == 'bg'){ // checks if the response is from BG
            //Something happened ...
    }

    var responseFromBg = response.data; // the response incase we need to use the message sent back... in this case should be 'hey yourself'


});

Background.js

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
  // From content script.
  if (sender.tab) {
    if (request.method == "fromContentScript"){

        localStorage.setItem("welcome-message",request.greeting); // in this case there will now be a localStorage variable called 'welcome-message' set with the value of 'hey hey!'. This will be viewable in the chrome:extensions page, click on the 'background.html / generated background.html' then view the 'Development Tools' or in Windows hit 'CTRL + SHIFT + I' and look at the 'LocalStorage' tab...

      sendResponse({who: "bg",data: "hey yourself"}); // this is the response sent back, 'who' tells the content page where is responding, so it can do something with the response if needed.
        }else{
      sendResponse({}); // snub them.
        }
  }
});

Manifest.json //只是因为这是一个明显的问题,你有......这里是我的大部分......

{
  "name": "Name here",
  "version": "1",
  "manifest_version": 2,
  "description": "Enter desc here.",  
    "browser_action": {
    "default_icon": "img/icon16.png",
    "default_popup": "popup.html"
  },    
    "background": {
    "scripts": ["background.js"]
  },
  "permissions": [
    "tabs", "*://*/*"
  ],
    "icons": { "16": "img/icon16.png",
           "48": "img/icon48.png",
          "128": "img/icon128.png" },
  "content_scripts": [
    {
      "matches": ["*://*/*"],
      "js": ["js/jquery-1.7.2.min.js","content_script.js"],
      "run_at": "document_end"
    }
  ]
}

本来会用你的例子,但我很匆忙。我试图尽可能仔细地解释所有的变种 - 抱歉:(

答案 2 :(得分:1)

<强>背景的script.js:

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    switch (request.command) {
        case 'setItem':
            localStorage[request.name] = JSON.stringify(request.data));
            return;
        case 'getItem':
            var retValue;
            if (typeof(localStorage[request.name]) === 'string') {
                retValue = JSON.parse(localStorage[request.name]);
            }
            sendResponse(retValue);
            return;
        case 'deleteItem':
            if (typeof localStorage[request.name] !== 'undefined') {
                delete localStorage[request.name];
            }
            return;
    }
});

如果密钥不在localStorage中,则getItem将返回undefined。您不应按照您的方式定义函数getItem,而应使用回调向后台发送消息,然后在调用回调时对该值执行某些操作。您无法从函数getItem返回值,但可以在调用时使用回调中的值:

function getItem(name, callback) {
    chrome.extension.sendMessage({command: 'getItem', name: name}, function(response) {
        if (typeof(callback) === "function") {
            callback(response);
        }
    });
}