关于注入脚本 + 本地存储的 Chrome 扩展

use*_*700 1 javascript google-chrome-extension content-script

我对我的第一个“将所有内容放在一起”的 Chrome 扩展程序感到困惑,我将描述我正在尝试做的事情,然后我是如何通过一些脚本摘录来解决这个问题的:

  1. 我有一个 options.html 页面和一个 options.js 脚本,它允许用户在文本字段中设置一个 url——这使用 localStorage 存储。
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 );
Run Code Online (Sandbox Code Playgroud)
  1. 我的 contentscript 将脚本“myscript”注入页面(因此它可以访问页面 html 中的 img 元素)
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);
Run Code Online (Sandbox Code Playgroud)
  1. myscript.js应该以某种方式获取本地存储数据并决定如何操作图像元素。

我从 html 源中抓取图像没有任何问题,但我似乎无法访问 localStorage 数据。我意识到它必须与具有不同环境的两个脚本有关,但我不确定如何克服这个问题——据我所知,我需要从 contentscript.js 注入 myscript.js,因为 contentscript.js 没有可以访问 html 源代码。

希望这里有人可以建议我缺少的东西。

谢谢,我很感激你能提供的任何帮助!

-安迪

Rob*_*b W 7

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

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

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

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

// 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
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

// Options page
function load_options() {
   chrome.storage.local.get('repl_adurl', function(items) {
       var repl_adurl = items.repl_adurl;
       default_img.src = repl_adurl;
       tf_default_ad.value = repl_adurl;
   });
}
function save_options() {
   var tf_ad = document.getElementById('tf_default_ad');
   chrome.storage.local.set({
       repl_adurl: tf_ad.value
   });
}
Run Code Online (Sandbox Code Playgroud)

文档