【问题标题】:Chrome extension contains errorsChrome 扩展程序包含错误
【发布时间】:2016-10-01 11:45:17
【问题描述】:

我决定冒险创建一个 chrome 扩展程序,并决定实现一个简单的扩展程序,以防止我每天访问 facebook/linkedin 超过 5 次。

但是,我不断收到一些错误,我似乎无法调试。它们是:

奇怪的是,当它似乎是在 chrome API 中定义时,它却说无法读取未定义。

这是我使用的文件:

manifest.json

{
  "manifest_version": 2,
  "name": "Distract Me Not",
  "version": "0.1",
  "permissions": ["webNavigation"],
  "content_scripts": [
  {
    "matches": [
     "https://*.facebook.com/","https://*.linkedin.com/"
    ],
    "js": ["content.js","jquery3.1.1.js","background.js"]
  }
]
}

content.js

chrome.webNavigation.onCompleted.addListener(function(details) {
    chrome.tabs.executeScript(details.tabId, {
        file: 'background.js'
    });
});

background.js

function getDate(){
    var today = new Date();
    var dd = today.getDate();
    var mm = today.getMonth()+1; //January is 0!
    var yyyy = today.getFullYear();

    if(dd<10) {
        dd='0'+dd
    } 

    if(mm<10) {
        mm='0'+mm
    } 

    today = dd+'/'+mm+'/'+yyyy;
    return(today);
}

function main() {
    appName = $.getJSON("settings.json" , function(json){
        return json["appName"];
    });

    websiteLimits = $.getJSON("settings.json" , function(json){
        return json["websiteLimits"];
    });

    currentPage = window.location.hostname;
    currentWebsiteLimit = websiteLimits[currentPage];

    checkFor = appName + getDate();
    item = localStorage.getItem(checkFor);
    if (item) {
        item = Number(item);
        if (item > currentWebsiteLimit) {
            document.write("Sorry! Your limit for " + currentPage + " has been reached for today.");
            return;
        }
        localStorage.setItem(checkFor,item+1);
        return;
    }
    localStorage.setItem(checkFor,1);
}

main();

settings.json

{"appName":"distract me not",
"websiteLimits":{"facebook.com":5,
                "linkedin.com":5}
}

这似乎相当简单,但它暗示了我。我可能遗漏了一些简单的东西,希望得到一些关于如何解决这个问题的指导!

谢谢! :)

更新:

我意识到文件应该按其他顺序排列,并且我没有清除以前的错误,所以我被误导了同样的错误正在发生。

但是,脚本的计数似乎不正确(content.js 中的警告行在一次重新加载时会发出两次警告)。有没有解决的办法?另外,我看到 $.getJSON 无法获取本地文件。有没有办法可以将设置抽象到另一个 json 并加载它,或者这是唯一的方法?

非常感谢! :)

manifest.json

{
  "manifest_version": 2,
  "name": "Distract Me Not",
  "version": "0.1",
  "permissions": ["webNavigation","tabs","https://*.facebook.com/","https://*.linkedin.com/"],
  "background":{
    "scripts":["background.js"]
  },
  "content_scripts": [
  {
    "matches": [
     "https://*.facebook.com/","https://*.linkedin.com/"
    ],
    "js": ["jquery3.1.1.js","content.js"]
  }
]
}

content.js

function getDate(){
    var today = new Date();
    var dd = today.getDate();
    var mm = today.getMonth()+1; //January is 0!
    var yyyy = today.getFullYear();

    if(dd<10) {
        dd='0'+dd
    } 

    if(mm<10) {
        mm='0'+mm
    } 

    today = dd+'/'+mm+'/'+yyyy;
    return(today);
}

function main(){
    var settings = {"appName":"distract me not",
                    "websiteLimits":{"www.facebook.com":5,
                                    "www.linkedin.com":5}
                    };

    appName = settings["appName"];
    websiteLimits = settings["websiteLimits"];
    currentPage = window.location.hostname;
    currentWebsiteLimit = websiteLimits[currentPage];

    alert(currentPage);

    checkFor = appName + getDate();
    item = localStorage.getItem(checkFor);
    if (item) {
        item = Number(item);
        if (item > currentWebsiteLimit) {
            document.write("Sorry! Your limit for " + currentPage + " has been reached for today.");
            return;
        }
        localStorage.setItem(checkFor,item+1);
        return;
    }
    localStorage.setItem(checkFor,1);
}

main();

background.js

chrome.webNavigation.onCompleted.addListener(function(details) {
    chrome.tabs.executeScript(details.tabId, {
        file: 'content.js'
    });
});

【问题讨论】:

  • 查看extension overview, architecture:内容脚本不同于背景页面。另请参阅 content script docs 以获取内容脚本中允许的 API 列表。
  • 感谢您的回复,但我不明白为什么需要重写。我在关注这个stackoverflow.com/questions/9862182/…
  • 我确实读过它,我设置了 background.js 来监听事件(将 content.js 更改为 background.js),同样,将 manifest.json 更改为将后台脚本作为 background.js和内容脚本为 content.js。仍然得到错误..正确的方法是如何做到这一点?
  • 抱歉,我已经更新了问题 :) 不知道错误不会自动清除,它现在可以正常工作,还有我在问题中提到的其他问题 :)跨度>
  • 现在你的问题是一个巨大的怪物,其中一半已经过时了。现有答案似乎解决了您更新的问题 - 请清理您的问题以仅包含更新版本。

标签: javascript jquery json google-chrome google-chrome-extension


【解决方案1】:

您的脚本在每次页面重新加载时运行两次,因为您在每次页面重新加载时包含两次。

看看你的代码就明白了

manifest.json

...
"content_scripts": [
{
  "matches": [
     "https://*.facebook.com/","https://*.linkedin.com/"
  ],
  "js": ["jquery3.1.1.js","content.js"]
}
...

这段代码的意思是:“请在任何页面中包含我的content.jsjquery3.1.1.js 脚本,该页面的url 与DOM Ready 上的https://*.facebook.com/https://*.linkedin.com/ 匹配”。

background.js

...
chrome.webNavigation.onCompleted.addListener(function(details) {
  chrome.tabs.executeScript(details.tabId, {
      file: 'content.js'
  });
});
...

这段代码的意思是:“请在每次webNavigation.onCompleted 触发时运行content.js”。

如您所见 - 在加载您的 LinkedIn 时,这两个条件都为真,因此脚本 content.js 运行两次,您会看到 2 个警报。

P.S>您只想限制对LinkedIn主页而不是子页面的访问是否正确?

【讨论】:

  • 这是正确的 - 仅在主页上点击。并感谢您的回复,我现在更好地理解了这一点:) 所以如果我理解正确,解决方案是让 content.js 基本上是空的?
  • 是的,您可以选择清除清单或背景中的 content_script 部分。我想如果您确定,您只想锁定 LinkedIn 和 Facebook 网站 - 更好的方法是保存 content_script,但删除背景页面。如果您想添加另一个锁 - 最好在清单中清理 content_script 部分并将此逻辑放在后台页面上。
  • 关于加载 JSON 配置的问题 - 您可以使用 &lt;input type='file'&gt; 字段选择文件系统上的文件,使用 HTML5 FileReader API 获取文件内容并使用 JSON.parse(...) 将其解析为 JSON。但请确保您没有在 popup.html 中使用 &lt;input type='file'&gt; - 在这种情况下您无法处理文件选择回调 - 您可以使用注入脚本或弹出窗口。关于 HTML5 FileReader 的好文档在这里:html5rocks.com/en/tutorials/file/dndfiles 如果需要,我可能会写教程,但这真的很容易。
猜你喜欢
  • 2014-08-05
  • 2016-08-20
  • 1970-01-01
  • 2013-12-28
  • 2021-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多