关于注入脚本+ localstorage的Chrome扩展程序

时间:2013-04-07 23:40:47

标签: javascript google-chrome-extension content-script

我通过我的第一个“把它放在一起”的Chrome扩展程序让我感到困惑,我会描述我想要做的事情,然后我会用一些脚本摘录来解决这个问题:

  1. 我有一个options.html页面和一个options.js脚本,允许用户在文本字段中设置一个网址 - 这是使用localStorage存储的。
  2. function load_options() {
       var repl_adurl = localStorage["repl_adurl"];
       default_img.src = repl_adurl;
       tf_default_ad.value = repl_adurl;
    }
    
    function save_options() {
       var tf_ad = document.getElementById("tf_default_ad");
       localStorage["repl_adurl"] = tf_ad.value;
    }
    
    document.addEventListener('DOMContentLoaded', function () {
       document.querySelector('button').addEventListener('click', save_options);
    });
    
    document.addEventListener('DOMContentLoaded', load_options );
    
    1. 我的脚本将一个脚本'myscript'注入页面(因此它可以访问页面的html中的img元素)
    2. var s = document.createElement('script');
      s.src = chrome.extension.getURL("myscript.js");
      console.log( s.src );
      (document.head||document.documentElement).appendChild(s);
      s.parentNode.removeChild(s);
      
      1. myscript.js 假设以某种方式获取本地存储数据,并确定如何操作图像元素。
      2. 我从html源代码中抓取图像没有任何问题,但我似乎无法访问localStorage数据。我意识到它必须与具有不同环境的两个脚本有关,但我不确定如何克服这个问题 - 据我所知,我需要从contentscript.js注入myscript.js,因为contentscript.js没有有权访问html源代码。

        希望有人在这里可以提出一些我不知道的事情。

        谢谢,感谢您提供的任何帮助!

        -Andy

1 个答案:

答案 0 :(得分:3)

首先:您不需要注入脚本来访问页面的DOM(<img>元素)。 DOM已经可用于内容脚本。

内容脚本无法直接访问扩展程序的localStorage进程,您需要在后台页面和内容脚本之间实现通信通道才能实现此目的。幸运的是,Chrome为此目的提供了一个简单的message passing API

我建议使用chrome.storage API代替localStoragechrome.storage的优点是它可用于内容脚本,它允许您在没有背景页面的情况下读取/设置值。目前,您的代码看起来非常易于管理,因此可以从同步localStorage切换到异步chrome.storage API。

无论您的选择如何,内容脚本的代码都必须异步读/写首选项:

// Example of preference name, used in the following two content script examples
var key = 'adurl';

// Example using message passing:
chrome.extension.sendMessage({type:'getPref',key:key}, function(result) {
    // Do something with result
});
// Example using chrome.storage:
chrome.storage.local.get(key, function(items) {
    var result = items[key];
    // Do something with result
});

正如你所看到的,两者之间几乎没有任何区别。但是,要使第一个工作,您还必须向后台页面添加更多逻辑:

// Background page
chrome.extension.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.type === 'getPref') {
        var result = localStorage.getItem(message.key);
        sendResponse(result);
    }
});

另一方面,如果要切换到chrome.storage,则必须稍微重写选项页面中的逻辑,因为当前代码(使用localStorage)是同步的,而{{{ 1}}是异步的:

chrome.storage

文档