从 content_scripts 和 browser_action 访问 chrome 同步数据

Accessing chrome sync data from content_scripts and browser_action

我正在尝试在 browser_action 和 content_scripts 之间共享数据。

目前,我遇到了一个问题,我可以访问 browser_action 页面中的数据(它 return 是正确的值,一旦设置并跨会话保存)。

但是,我似乎无法访问 content_script 中的数据,即使在 browser_action.js 中保存之后也是如此。 console.log总是return"undefined"为值。

预期的工作流程是:

content_script:

if syncData === undefined {
    /* Do default stuff */
} else if syncData {
    /* Do stuff if set to true */
} else {
    /* Do stuff if set to false */
}

browser_action.js:

/* Allow user to set syncData so that it saves across page refreshes and is accessible by content_script */

manifest.json

{
    "manifest_version": 2,

    "name": "Name",
    "description": "Description",
    "version": "1.0",
    "content_scripts": [
        {
            "js": ["content_script.js"]
        }
    ],
    "browser_action": {
        "default_icon": "icon128.png",
        "default_popup": "browser_action.html"
    },
    "icons": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
    },
    "permissions": [
        "storage"
    ]
}

content_script.js

chrome.storage.sync.get('descriptionEnabled', function (data) {
    console.log(data.descriptionEnabled)
});

browser_action.js

/*jslint browser: true*/
/*global window, document, alert, chrome */

window.onload = function () {
    "use strict";
    chrome.storage.sync.get('descriptionEnabled', function (data) {
        if (data.descriptionEnabled === true) {
            document.getElementById("settingsId").value = "on";
        } else if (data.descriptionEnabled === false) {
            document.getElementById("settingsId").value = "off";
        }
    });
    document.getElementById("settingsId").onchange = function () {
        if (document.getElementById("settingsId").value === "on") {
            chrome.storage.sync.set({'descriptionEnabled': true});
        } else {
            chrome.storage.sync.set({'descriptionEnabled': false});
        }
    };
};

browser_action.html

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
        <script type="text/javascript" src="browser_action.js"></script>
        <title>Description Background Page</title>
    </head>
    <body>
        <div>Display Saved Notifications?</div>
        <div>
            <select id="settingsId">
                <option value="on">Yes</option>
                <option value="off">No</option>
            </select>
        </div>
    </body>
</html>

要为您的扩展存储用户数据,您可以使用 storage.syncstorage.local。使用 storage.sync 时,存储的数据将自动同步到用户登录的任何 Chrome 浏览器,前提是用户已启用同步。

当Chrome离线时,Chrome将数据存储在本地。下次浏览器在线时,Chrome同步数据。即使用户禁用同步,storage.sync 仍然有效。在这种情况下,它的行为与 storage.local.

相同

查看此 document 以获取更多信息和示例代码。

对于您收到的错误,您可以通过阅读本文了解更多信息blog。它在这里解释了console.log

中未定义的含义和原因

也尝试检查这个 SO question。它认为它将对您在内容脚本和后台操作方面有很大帮助。

首先,不要忘记在 manifest.json 中添加 matches 字段。

您的代码运行良好,但请注意,您在弹出页面加载和选项更改后设置了存储,因此您需要刷新网页以重新加载内容脚本以使其再次执行,然后您将从当前网页的控制台中看到 true 或 false。

虽然消息传递是内容和扩展脚本之间最常用的通信方式,但您也可以使用存储。在您的内容脚本中,为存储的更改事件添加一个侦听器:

chrome.storage.onChanged.addListener(function(changes, areaName){
if(areaName=="sync"){
  if(changes.descriptionEnabled) 
    console.log(changes.descriptionEnabled.newValue);
  }
});

存储,尤其是本地存储,速度非常快,所以有时候,当您无论如何都需要将数据保存到存储中时,监听存储更改而不是消息是有意义的。

与消息传递的另一个区别是此事件将仅在更改值时触发。如果您的值为 true,并且新值也为 true,则不会触发该事件。