0

我了解如何在清单中包含这样的内容:

"exclude_matches" : ["*://somesite.somewhere.com/*"],

但是,这对于许多 URL 似乎没有用。

有没有办法检查外部文件以查看 URL 或模式是否存在?

我可以在 URL 或模式存在时显示通知以提醒用户扩展程序不可用吗?

4

2 回答 2

1

您不能将“exclude_matches”属性绑定到外部文件。

如果您需要检查包含 URL 或模式的文件,我建议使用Programmatic Injection

  1. 在您的背景页面(或更好的事件页面)中注册一个适当的监听器,例如 chrome.tabs.onUpdated.addListener()

  2. 当标签的位置更新时,让您的背景页面或事件页面检查包含 URL/模式的捆绑 js 文件,并决定是否应该注入内容脚本。

  3. 最后,使用chrome.tabs.executeScript()将脚本注入网页(如有必要)。

根据要求,一些未经测试的代码可以帮助您入门:

manifest.json中:

...
// 1. Ask permission to listen for changes in tabs
// 2. Ask permission to "interfere" with any web-page 
// (using the "http" or "https" schemes - modify appropriately for other schemes)
"permissions": {
    ...
    "tabs",
    "http://*/*", 
    "https://*/*"
},
...
// Include the file with the URLs and/or patterns to check
// in your background- or event-page.
"background": {
    "persistent": false,   // <-- Recommended, but optional
    "scripts": [
        "background.js",
        "lotsOfURLsAndOrPatterns.js"
    ]
},
...

很多 URLsAndOrPatterns.js 中

...
// E.g.:
var excludedURLsArray = [
    "<1st url...>",
    "<2nd url...>",
    ...
];
...

background.js中:

// Add a listener for the "onUpdated" event
chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
    if (info.url) {
        // The URL has changed - you can device other methods for checking
        // if you need to inject the tab, according to your particular setup
        for (var i = 0; i < excludedURLsArray.length; i++) {
            // Look for an exact match with an excluded URL
            // (modify according to your needs - e.g. check host only, etc)
            if (info.url == excludedURLsArray[i]) {
                // No injection - inform user and return
                alert("Extension not available on '" + info.url + "'.\n"
                      + "You are on your own !");
                return;
            }
        }

        // Ending up here means we must inject...
        chrome.tabs.executeScript(tabId, {
            "file": "myContentScript.js",
            "allFrames": false   // <-- or whatever suits you
        }
    }
};
于 2013-10-13T18:49:44.933 回答
1

新解决方案,考虑到 OP 对以下方面的要求:

  1. 用户不可修改的 URL 列表。
  2. 可以集中更新并立即生效的 URL 列表。

由于您无法将“exclude_matches”属性绑定到外部文件,因此您可以通过 AJAX 和Programmatic Injection实现您想要的:

  1. 使用chrome.tabs.onUpdated.addListener()在您的背景页面(或更好的事件页面)中注册一个适当的侦听器

  2. 当标签的位置更新时,让您的背景页面或事件页面通过对您的服务器的 AJAX 请求获取 URL 列表,并决定是否应该注入内容脚本。(根据您的确切要求,您可以让您的后台页面定期获取更新的文件,而不是在每次选项卡更新时都要求它以获得更好的性能。)

  3. 最后,使用chrome.tabs.executeScript()将脚本注入网页(如有必要)。

看看这里开始使用 AJAX。

最后,一些演示,可以使用的工作代码:

manifest.json中:

...
// 1. Ask permission to listen for changes in tabs
// 2. Ask permission to "interfere" with any web-page 
// (using the "http" or "https" schemes - modify appropriately for other schemes)
"permissions": {
    ...
    "tabs",
    "http://*/*", 
    "https://*/*"
},
...
// Include the file with the URLs and/or patterns to check
// in your background- or event-page.
"background": {
    "persistent": false,   // <-- Recommended, but optional
    "scripts": [
        "background.js"
    ]
},
...

content_script.js中:

// Do stuff...
alert("I've been injected !\nHow cool is that !");

background.js中:

var ajaxURL = "http://url.to.your/server";

// Asynchronously fetch the list of excluded URLs
// (use synchronous calls if it better suits your purpose)
function getExcludedURLs(successCallback, failureCallback) {
    var ajaxRequest = new XMLHttpRequest();
    ajaxRequest.addEventListener("readystatechange", function() {
        if (ajaxRequest.readyState == 4) {   // <-- the request has completed
            if (ajaxRequest.status == 200) {
                successCallback(ajaxRequest.responseText);
            } else {
                failureCallback(ajaxRequest.statusText);
            }
        }
    });
    // Send an HTTP GET request and get the response asynchronously
    ajaxRequest.open("GET", url, true);
    ajaxRequest.send(null);
}

// A function to be called on AJAX request failure:
//   alerts the user regarding the failure
function onAJAXFailure(statusText) {
    alert("Unable to fetch the excluded URLs list :(\n"
          + "Error: " + statusText);
}

// Retuns a function to be called on AJAX request success:
//   test if the URL is in the list and injects the content script
// If you feel like delving into some more advanced concepts, 
// look for "Closures in JS", e.g.: 
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures
function onAJAXSuccess(tab) {
    return function(responseText) {
        var excludedURLsArray = JSON.parse(responseText);
        for (var i = 0; i < excludedURLsArray.length; i++) {
            // Look for an exact match with an excluded URL
            // (modify according to your needs - e.g. check host only, etc)
            if (tab.url == excludedURLsArray[i]) {
                // No injection - inform user and return
                alert("Extension not available on '" + tab.url + "'.\n"
                      + "You are on your own !");
                return;
            }
        }

        // Ending up here means we must inject...
        chrome.tabs.executeScript(tab.id, {
            "file": "content_script.js",
            "allFrames": false   // <-- or whatever suits you
        });
    };
}

// Add a listener for the "onUpdated" event
chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
    if (info.status && (info.status == "complete")) {
        getExcludedURLs(onAJAXSuccess(tab), onAJAXFailure);
    }
});

在服务器端,您需要一种方法来发回 JSON 编码的排除 URL 数组。有很多方法可以做到这一点(取决于使用的服务器端技术)。这只是 PHP 中的一个示例实现(为了完整起见)。

http://url.to.your/server

<?php
$excludedURLs = array(
    "http://stackoverflow.com/",
    "http://www.stackoverflow.com/",
    "http://stackoverflow.com/questions/tagged/google-chrome-extension",
    "http://www.stackoverflow.com/questions/tagged/google-chrome-extension"
);

echo(json_encode($excludedURLs));
exit();
?>
于 2013-10-24T18:58:29.990 回答