javascript - 在 Chrome 扩展程序的 background.js 中访问用户选项

标签 javascript google-chrome-extension

我正在尝试访问 chrome.storage.sync,我在 background.js 中存储了一些用户选项,但 chrome.storage.sync.get 的异步性质导致了我的问题。

如果我尝试在我的 chrome.webRequest.onBeforeRequest.addListener 中使用 chrome.storage.sync.get,回调速度不够快,函数无法使用它。

我曾尝试将用户选项添加为 background.js 中的全局变量,但在我看来该值不会持续存在。

还有其他人在 background.js 中使用用户选项吗?

function getoption(){
  chrome.storage.sync.get({
    radarpref: 'nothing',
  }, function(items) {
  console.log(items.radarpref);
  return items.radarpref;
    
  });

}
var hold = getoption();
console.log (hold) //this returns hold value

chrome.webRequest.onBeforeRequest.addListener(
  function(info) {

    //this doesn't work - yet
   console.log('i dont see the hold');
	console.log(hold) //hold not returned when callback ran
  ...
  

最佳答案

如果您需要同步使用来自任何异步存储的设置 - 最好的方法是缓存它。

您需要在 background.js 上将设置加载到缓存中启动然后每次都需要更新缓存chrome.storage.onChanged事件触发。

示例操作方法:

list .js

{
    "manifest_version": 2,
    "name": "Settings Online demo",
    "description": "Settings Online demo",    
    "applications": {
        "gecko": {
            "id": "852a5a44289192c3cd3d71e06fdcdb43b1437971@j2me.ws"
        }
    },
    "version": "0.0.1",
    "background": {
        "scripts": ["background.js"]
    },
    "permissions": [
        "storage",
        "webRequest",
        "webRequestBlocking",
        "<all_urls>"
    ],
    "options_ui": {
        "page":"properties.html",
        "chrome_style": true
    }
}

请注意,如果您需要在 firefox 上使用它,则需要具有非临时应用程序 ID,<all_urls>需要权限才能访问任何 url 请求处理。

background.js

((storage) => {
    let settings = (function(properties) {

        // Save settings
        this.set = (properties,ok) => {
            for(key in properties || {}){
                this[key]=properties[key];
            }
            storage.set(
                properties
            ,() => {
                ok(settings);
            });
        };

        //Default values processing
        for(key in properties || {}){
            this[key]=properties[key];
        }

        // Initial settings read
        storage.get(properties,(properties) => {
            for(key in properties){
                this[key]=properties[key];
            }
        });


        // Listen settings change and cache it
        chrome.storage.onChanged.addListener((msg) => {
            for(key in msg){
                this[key]=msg[key].newValue;
            }
        });

        return this;
    }).call({},{"property":"default","name":"me"})

    chrome.webRequest.onBeforeRequest.addListener(
      function(info) {
       // Update and persist settings
       settings.set({"lastRequest":info},()=>{console.log("Settings saved")});
       console.log('Catch', settings.name,settings.property);
    },{urls:["https://*/*"]});
})(chrome.storage.sync || chrome.storage.local);

请注意,我使用 chrome.storage.sync || chrome.storage.local因为有些浏览器(Opera,移动浏览器)不支持同步存储,但是支持本地存储。

以及属性页,看看属性变化是如何处理的: properties.html

<html>
    <head>
        <script src="properties.js" type="text/javascript"></script>
    </head>
    <body>
        <label>Property:<input id="property" type="text"></label>
        <input id="save-properties" value="save" type="submit">
    </body>
</html>

属性.js

((storage) => {
    let saveOptions = () => {
        let property = document.getElementById("property").value;

        storage.set({
            "property": property
        },() => {
            window.close();
        });
    }

    let restoreOptions = () => {
        storage.get({
            "property": "default"
        }, (properties) => {
            document.getElementById("property").value = properties.property;
        });
        document.getElementById("save-properties").addEventListener("click", saveOptions);
    }
    document.addEventListener("DOMContentLoaded", restoreOptions);
})(chrome.storage.sync || chrome.storage.local);

就是这样:)

P.S> 这个解决方案有一个弱点:如果您的应用程序对设置敏感并且不能使用默认设置,或者您需要确保在启动时使用自定义设置 - 您需要延迟背景。 js 在未加载设置时启动。您可以通过回调或 promise 来实现它:

background.js - 等待回调加载设置

((storage) => {
    let settings = (function(properties) {

        // Update settings
        this.set = (properties,ok) => {
            for(key in properties || {}){
                this[key]=properties[key];
            }
            storage.set(
                properties
            ,() => {
                ok(settings);
            });
        };

        //Default values processing
        for(key in properties || {}){
            this[key]=properties[key];
        }

        // Listen settings change and cache it
        chrome.storage.onChanged.addListener((msg) => {
            for(key in msg){
                this[key]=msg[key].newValue;
            }
        });

        // Initial settings read
        storage.get(properties,(properties) => {
            for(key in properties){
                this[key]=properties[key];
            }
            mainLoop();
        });

        return this;
    }).call({},{"property":"default","name":"me"})

    let mainLoop = () => {

        //.. all you settings-sensitive code
        chrome.webRequest.onBeforeRequest.addListener(
          function(info) {
            // Update settings and persist it       
            settings.set({"lastRequest":info},()=>{console.log("Settings saved")});
           console.log('Catch', settings.name,settings.property);
        },{urls:["https://*/*"]});
    };

})(chrome.storage.sync || chrome.storage.local);

background.js - 等待设置加载 promise

((storage) => {
    let settings = ((properties) => {

        this.set = (properties) => {
            for(key in properties || {}){
                this[key]=properties[key];
            }
            return new Promise((ok,err) => {
                storage.set(
                    properties
                ,() => {
                    ok(settings);
                });
            });
        };

        return new Promise((ok,err) => {
            //Default values processing
            for(key in properties || {}){
                this[key]=properties[key];
            }

            // Listen settings change and cache it
            chrome.storage.onChanged.addListener((msg) => {
                for(key in msg){
                    this[key]=msg[key].newValue;
                }
            });

            // Initial settings read
            storage.get(properties,(properties) => {
                for(key in properties){
                    this[key]=properties[key];
                }
                ok(this);
            });
        });
    }).call({},{"property":"default","name":"me"}).then((settings) => {
        //.. all you settings-sensitive code

        chrome.webRequest.onBeforeRequest.addListener(
          function(info) {
            // Update settings and persist it       
            settings.set({"lastRequest":info}).then(()=>{console.log("Settings saved")});
            console.log('Catch', settings.name,settings.property);
        },{urls:["https://*/*"]});
    }).catch(()=>{});

})(chrome.storage.sync || chrome.storage.local);

阅读更多

  1. 存储规范/firefox: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage
  2. 存储规范/ Chrome :https://developer.chrome.com/apps/storage
  3. 权限请求/firefox: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Request_the_right_permissions

关于javascript - 在 Chrome 扩展程序的 background.js 中访问用户选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52862728/

相关文章:

javascript - 找到开始字符串的制表符数量的最佳/最快方法是什么?

javascript - 从 Chrome 扩展中 Hook Websocket

javascript - 将数据从 background.js 发送到 popup.html

google-chrome-extension - 谷歌浏览器 : updating extension in "Developer mode" (locally) from userscript

javascript - 非常奇怪的 JavaScript 错误

javascript - 我试图在纯函数中将值移动到父节点

javascript - 如何为特定页面显示 page_action?

google-chrome - Chrome 扩展程序 : Hide and show the browser action icon

Javascript 关联数组

javascript - 如何为每个用户通过函数进行解析后台作业循环?