根据URL列表防止扩展运行的最佳方法并通知?

时间:2013-10-13 17:47:10

标签: google-chrome-extension

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

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

但是,这似乎对许多网址都没用。

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

当网址或模式存在时,是否可以显示通知以提醒用户该扩展程序不可用?

2 个答案:

答案 0 :(得分:1)

您无法将“exclude_matches”属性绑定到外部文件。

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

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

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

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

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

    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"
        ]
    },
    ...
    

    lotsOfURLsAndOrPatterns.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
            }
        }
    };
    

答案 1 :(得分:1)

新解决方案,考虑到OP的要求:

  1. 用户无法修改的网址列表。
  2. 可以集中更新并立即生效的网址列表。
  3. 由于您无法将“exclude_matches”属性绑定到外部文件,因此您可以通过AJAX和 Programmatic Injection 实现您想要的功能:

    1. 使用 chrome.tabs.onUpdated.addListener()

    2. 在后台页面(或更好的事件页面)中注册合适的聆听者
    3. 更新标签的位置后,让您的背景或事件页面通过向服务器发出AJAX请求来获取URL列表,并决定是否应该注入内容脚本。 (根据您的具体要求,您可以让您的后台页面定期获取更新的文件,而不是在每次更新标签时都要求它以获得更好的性能。)

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

    5. 看一下 here ,开始使用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();
      ?>