2

我是 javascript 新手,正在尝试学习 Chrome 扩展程序。我已经搜索了我能想到的问题的每一个变体,但我找到的答案不适用于我的具体问题。我已经阅读了 chrome 扩展的教程,而我认为应该起作用的实际上并没有起作用。

我写的扩展没有 html 页面,只有一个图标,因为它应该一直运行。它实际上完美地工作,阻止对某个聊天程序的调用以防止聊天窗口打开。它是为必须在网站上呆很长时间并且不想一直关闭聊天窗口的测试人员编写的。

问题是该扩展适用于所有网站,而我只希望它适用于一个网站。也就是说,当用户在使用相同聊天软件的其他网站时,聊天窗口也会被屏蔽。

我读到的内容让我相信,在 manifest.json 的 content_scripts 块中匹配我想要使用的网站会导致扩展只在匹配的网站中运行。这没用。事实上,如果我完全从清单文件中取出 content_scripts 块,扩展的工作原理完全相同。调用 javascript 函数并阻止聊天窗口。因此,出于某种原因, content_scripts 块被忽略了。作为一个 javascript 菜鸟,我想我一定错过了一个关键步骤。我从示例中获得了大部分代码,只是稍微修改了一下。任何人都可以帮忙吗?

清单.json:

    {
  "manifest_version": 2,
    "version": "1.0",
  "name": "ChatBlock",
  "description": "Shut down liveperson chat on mywebsite.com before it runs.",

  "permissions": [          
    "tabs",
    "webRequest",
    "webRequestBlocking",
    "*://sales.liveperson.net/"
   ],
   "web_accessible_resources": ["jquery-1.10.2.min.js"],
   "content_scripts": [
    {
      "matches": ["*://*.mywebsite.com/*"],
      "js": ["jquery-1.10.2.min.js"]
    }
   ],
   "browser_action": {
    "default_icon": "chatblockIcon.png"
   },
   "background": {
    "scripts": ["avoid.js"]
   }

  }

javascript 文件(avoid.js):

chrome.webRequest.onBeforeRequest.addListener(
  function(details) {   
    return {
        cancel: true
        }; 
  },
  {urls: ["*://sales.liveperson.net/*"]},
  ["blocking"]);

编辑:我已经从清单中删除了对 jquery 的引用。该工具在没有它的情况下仍然可以正常工作,因此下面的评论是正确的,不需要它 - 感谢@ExpertSystem。但封锁仍然发生在所有网站上。我之前(在发布此问题之前)尝试过@ExpertSystem 的第二个建议,即明确检查所需网站的选项卡或检查引荐来源网址,但我无法找到正确的 JavaScript 语法以使其正常工作。此外,如果可能的话,我对使用“matches”属性非常感兴趣,因此 javascript 更通用。我仍然对为什么“匹配”不起作用感到困惑 - 我在匹配属性方面做错了什么?

新版本的 Manifest.json:

{
  "manifest_version": 2,
    "version": "1.0",
  "name": "ChatBlock",
  "description": "Shut down liveperson chat on myWebsite.com before it runs.",

  "permissions": [          
    "tabs",
    "webRequest",
    "webRequestBlocking",
    "*://sales.liveperson.net/"
   ],
   "content_scripts": [
    {
      "matches": ["*://*.myWebsite.com/*"],
      "js": ["avoid.js"]
    }
   ],
   "browser_action": {
    "default_icon": "chatblockIcon.png"
   },
   "background": {
    "scripts": ["avoid.js"]
   }

  }
4

1 回答 1

2

您正在注入 jquery 作为您的内容脚本,但她自己没有用。另外,您正在liveperson.com后台页面中侦听 webRequests 并为每个站点取消它们。

您必须设计一种方法来区分来自的请求mywebsite.com并仅阻止它们。(我也没有看到注入 jquery 的任何理由。)

区分请求的可能方法可能是:

  1. 通过一个标题details.requestHeaders(如果mywebsite.com设置了这样一个适当的标题,例如referer)。
  2. 跟踪mywebsite.com在后台页面中运行的打开选项卡(通过chrome.tabs.onUpdated侦听器)并基于details.tabId.

...但我敢肯定还有更多。


我上面第二个选项的演示实现......

清单.json:

...
"background": {
    // Unfortunately, chrome.webRequest 
    // requires a persistent background page
    "persistent": true,
    "scripts": [
        "background.js"
    ]
},

"content_scripts": [
    {
        "matches": [
            "*://<website1>/*",
            "*://<website2>/*",
            ...
        ],
        "js":         ["content.js"],
        "run_at":     "document_idle",
        "all_frames": false
    }
 ],

"permissions": [
    "webRequest",
    "webRequestBlocking",
    "*://sales.liveperson.net/*"
]

内容.js:

chrome.runtime.sendMessage({ text: "block_me" });

背景.js:

// Add a tab ID to the blocking list
function addToList(tabId) {
    localStorage.setItem(tabId, "1");
    console.log("Added to list: tab " + tabId);
    console.log("Currently blocking tabs: ", localStorage);
}

// Checks if a tab ID is in the blocking list
function isInList(tabId) {
    return (localStorage.getItem(tabId) !== null);
}

// Remove a tab ID from the blocking list
function removeFromList(tabId) {
    localStorage.removeItem(tabId);
    console.log("Removed from list: tab " + tabId);
    console.log("Currently blocking: ", localStorage);
}

// Listen for messages from content scripts
chrome.runtime.onMessage.addListener(function(msg, sender) {
    if (msg.text && (msg.text == "block_me")) {
        addToList(sender.tab.id);
    }
});

// Stop blocking a tab when its is closed
chrome.tabs.onRemoved.addListener(removeFromList);

// Stop blocking a tab when its is updated
// (If applicable, the newly injected content script will notify us.)
chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
    if (info.status && (info.status == "loading")) {
        removeFromList(tabId);
    }
});


// Handle a web-request, i.e. either allow it or block it
function handleRequest(details) {
    var block = isInList(details.tabId);
    console.log("Request from tab " + details.tabId + " - Blocked: " + block);
    console.log("Request details: ", details);
    return { cancel: block };
}

// Block any request to 'sales.liveperson.net',
// if it originates from a tab in our blocking list.
chrome.webRequest.onBeforeRequest.addListener(
        handleRequest,
        { urls: ["*://sales.liveperson.net/*"] },
        ["blocking"]);

(对于生产部署,您可以删除console.log调用。)

于 2013-10-26T06:46:38.787 回答