1
chrome.webRequest.onBeforeRequest.addListener(function(details) {
    if (localStorage.on == '1') {
        return {cancel:true};
    }
}, {urls: ["*://*.domain1.net/*","*://*.domain2.com/*","*://*.domain3.com/*"], types: ["script","xmlhttprequest","other"]}, ["blocking"]);

I don't see any way I can negate the URL pattern. Basically I want to match and block everything except those 3 domains. I thought of returning cancel:true for and the exact content for the 3 domains. First of will that work or will one listener "over-take" the other? How can I return the exact content (So no more cancel:true).

iordanis
  • 1,284
  • 2
  • 15
  • 28
  • What are you trying to achieve? – guest271314 May 30 '16 at 23:17
  • Block all javascript/bloatware that doesn't come from the domain or co-domains of a specific website. – iordanis May 30 '16 at 23:20
  • See http://stackoverflow.com/questions/15765451/chrome-extension-to-efficiently-block-domains , http://stackoverflow.com/questions/18158297/blocking-request-in-chrome , http://stackoverflow.com/questions/4663359/google-chrome-extension-how-to-turn-javascript-on-off – guest271314 May 30 '16 at 23:36
  • It's not really related to what I am asking. First link talks about blocking SPECIFIC sites, I want to UNBLOCK, specific sites and block EVERYTHING else. – iordanis May 30 '16 at 23:42
  • @lordanis What do you mean by _"UNBLOCK"_? Only you would be initially blocking content, yes? – guest271314 May 30 '16 at 23:44
  • So, I want to block every website in the internet from loading external resources except 3 domains. You can think of it as black listing everything except those 3 domains. So I thought there would be a way to negate the search pattern for the URLs but I realized it there is no support. So now I am just analyzing the details variables and checking each URL with the 3 domains I have. – iordanis May 30 '16 at 23:47
  • Also how can I just return the content for the onBeforeRequest to complete the request normally? – iordanis May 30 '16 at 23:51
  • _"So, I want to block every website in the internet from loading external resources except 3 domains."_ Does "resources" include `.css`? Or only `javascript`? By "loading" do you mean prevent the site from loading `javascript` entirely? Or prevent `javascript` from being run while the extension is running? – guest271314 May 30 '16 at 23:53

2 Answers2

3

The following example illustrates how to block all requests, except requests to domain1.net and domain2.net:

    chrome.webRequest.onBeforeRequest.addListener(
       function(details) {
         return {cancel: details.url.indexOf(".domain2.net/") == -1 && details.url.indexOf(".domain1.net/") == -1};
       },
    {urls: ["<all_urls>"]},
    ["blocking"]);

I can't see any way to negate the URL pattern in the documentation

The answer below, provided by Xan, has a better approach to validate the domain1.net and domain2.net URL's.

Paulo Prestes
  • 484
  • 2
  • 8
3

While the answer by Paulo Prestes is mostly correct (including the fact that "negative" filters are not possible), the filter suggested is trivially bypassed.

Consider: https://example.com/something?foo=.domain2.net/

This is matched by the rule, but obviously not intentional. Adding an unexpected parameter won't affect most pages, and as such it's quite a trivial bypass.

A collection of regular expressions tuned to extract the domain should be more robust:

function validUrl(url) {
  // RegEx, explained:
  // ^              at the beginning of the string
  // http           exactly "http"
  // s?             "s" or nothing
  // :\/\/          exactly "://"
  // ([^\/]+\.)?    (one or more not-"/" followed by ".") or nothing
  // domain\.net\/  exactly "domain1.net/"

  return /^https?:\/\/([^\/]+\.)?domain1\.net\//.test(url) ||
         /^https?:\/\/([^\/]+\.)?domain2\.net\//.test(url) ||
         /^https?:\/\/([^\/]+\.)?domain3\.net\//.test(url) 
}

/* ... */
  return {cancel: !validUrl(details.url)};
/* ... */
Xan
  • 74,770
  • 16
  • 179
  • 206
  • This also matches `http://notdomain1.net/` and `http://domain1.net.somethingelse.example.com/`. I suggest `/^https?:\/\/([^\/]+\.)?(domain1\.net|domain2\.net|domain3\.net)\//.test(url);` – Rob W May 31 '16 at 17:48
  • Thanks! I'm going to keep those 3 separate. Do you have a link to the question where there's an implementation of Chrome match patterns? – Xan May 31 '16 at 17:50
  • 1
    The edit does still not fix the second issue, `http://domain1.net.somethingelse.example.com` still matches. That's why I put a `/` at the end of the pattern. About the question with the implementation of Chrome's match patterns, I think that you have this in mind: https://stackoverflow.com/questions/12433271/can-i-allow-the-extension-user-to-choose-matching-domains – Rob W May 31 '16 at 18:11
  • Fixed (sorry, not paying enough attention today) and thanks, that was what I had in mind. – Xan May 31 '16 at 18:12
  • yeah I think this is a nice approach. I will test it when I get a chance – iordanis May 31 '16 at 19:36
  • I would delete my answer and make this answer the correct, if I could. It is a very nice approach @Xan! – Paulo Prestes Jun 01 '16 at 01:48