访问另一个JS文件中的数组 - Chrome扩展程序

4

嗨,我正在制作一个谷歌浏览器的扩展程序,用于练习,它是一个简单的网站屏蔽器。我有两个不同的JS文件需要共享包含要屏蔽的URL的同一数组。

  • background.js 处理网络请求和阻止网站
  • options.html 是选项页面,用户可以编辑要屏蔽的URL,它调用 storeURL.js 以便将所有元素存储在html页面列表中,并存储到js数组中。到目前为止没有问题。

然而,我无法从 background.js 中访问 storeURL.js 中的数组。似乎它们在两个不同的实例中被调用。如果我尝试在我的 background.html 中同时包含 storeURL.js 和 background.js,那么将会运行两个完全独立的 storeURL.js 脚本。

我该怎么做?我应该将 storeURL.js 中的数组内容存储到文件中吗?

一些示例:

background.js

chrome.webRequest.onBeforeRequest.addListener(
    blocking,["blocking"]);
    { urls: blockedURLS, types: [] }, ["blocking"]);

storeURL.js会根据options.html中的列表填充数组。

var blockedURLS = [];
        $('li').each(function(i, elem) {
            blockedURLS.push($(elem).text());
        });

我的background.js文件中的blockedURLS出现了未定义的情况。我还尝试将options.html文件指向background.js,并使用以下方式在一个文件中包含所有js:

<script type="text/javascript" src="background.js"></script>

然而,当我这样做时,似乎调用了第二个background.js而不仅仅是指向已经运行的那一个。
感觉我到了死胡同,可能有一个简单的解决方案可以修复我的问题。我对JS/Chrome扩展程序还相当陌生。
感谢您抽出时间阅读这篇文章!
编辑: 经过一些尝试,我能够访问我的background.js中的blockedURL数组。但它从未更新。
var blockedURLS = ["hi"] ;

    var list = document.getElementById('list');
    $("#saveList").click(function(e) {
        e.preventDefault();
        localStorage.setItem('todoList', list.innerHTML);
        alertify.success("You have saved your list.");

        //Pushes each element in the list from options.html into the urls array
        blockedURLS = [];
        $('li').each(function(i, elem) {
            blockedURLS.push($(elem).text());
        });
        alert("Currently blocked:\n" + blockedURLS);
    });
    $("#reset").click(function(e) {
        e.preventDefault();
        localStorage.clear();
        location.reload();
    });

    loadToDo();

    function loadToDo() {
      if (localStorage.getItem('todoList')){
        list.innerHTML = localStorage.getItem('todoList'); 
    }
    }

应该发生的是,当我进入我的options.html并保存列表后,“hi”应该被替换为我列表中的所有不同URL。然而实际情况并非如此。尽管如此,在警报中打印的blockedURL数组是正确的。

可能是重复的问题,与在Chrome扩展中的后台脚本之间如何传递变量值相关。参考链接 - Zig Mandel
2个回答

0

最近我不得不使用这种东西。我从来没有找到一个真正好的方法来做...所以我使用了Chrome扩展API的Storage API。但是这并不是很好用,因为所有方法都是异步的,所以你不能简单地执行

myValue = chrome.storage.local.get("MyValue")

如果您想要,我已经制作了一个对象,可以自动存储数据在Chrome存储中,但允许简单和同步的调用,例如myValue = storage.myValuestorage.myValue = "something"

这里是Github链接

它是用CoffeeScript编写的,所以您可以在bin文件夹中找到JavaScript文件。生成的JavaScript不是很容易阅读/修改,但是通过阅读CoffeeScript代码,您可以简单地理解其思想。

如果您想了解更多信息,我可以解释它的工作原理。请在评论中告诉我,我会更新我的回复。

请注意,这是我为自己使用编写的代码,因此它不是我曾经编写过的最干净和没有错误的代码 :-) 但它运行良好。

编辑:我忘记说您需要在所有页面/内容脚本中包含这两个文件,当然。

哦,对于我的糟糕英语,我很抱歉...它实际上不是我的主要语言;-)


你的方法和库忽略了存储“set”可能失败的事实,你的库将继续返回尝试设置的值(后来失败)。 - Zig Mandel
是的,就像我说的,这样做非常容易。如果你需要检查错误,可以添加一个错误处理程序作为示例。 - Emrys Myrooin
不行,因为在使用你的库获取值之后,错误处理程序将会运行。 - Zig Mandel
是的,你的脚本不会因为错误而直接停止。它会使用旧值继续运行,之后你可以处理错误。这是处理分布式系统错误的另一种方法。 - Emrys Myrooin
1
是的,你不能使用它来存储大量的数据。 - Emrys Myrooin
显示剩余4条评论

0

我必须使用以下命令:

var bg = chrome.extension.getBackgroundPage();

那么我可以通过以下方式访问blockedURLS数组:

alert(bg.blockedURLS);

同时也通过编辑数组来实现

chrome.extension.getBackgroundPage().blockedURLS = [];

这将把它设为空数组。

感谢大家的帮助,它帮助我思考了不同的方法来解决这个问题。


这是相当粗糙的方法,它会使你的代码耦合度非常紧密。使用消息传递/存储可能会更好。 - Xan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接