Search code examples
javascriptgoogle-chromegoogle-chrome-extension

Need help using chrome.webRequest to block a website using a Chrome Extension


I've been working on an extension for some time, and I encountered a problem... I made a button to toggle the blocking of the website, using this code:

$('#togglesafety').click(function(){
        chrome.storage.sync.get(['toggle'],function(website){

            var newTotal = "";
            if(!(website.toggle)){
                newTotal = "Enabled";
            }
            else{
                if(website.toggle == "Enabled"){
                    newTotal = "Disabled";
                }
                else{
                    newTotal = "Enabled";
                }
            }
            chrome.storage.sync.set({'toggle': newTotal}, function(){},)
            $('#toggled').text(newTotal);
        });
    });

And then blocking a list of blacklisted websites using this code:

const blockedWebsitesUrl = [
    "https://*.example.com/*"
]

chrome.storage.sync.get(["toggle"],function(website){
    if(website.toggle == "Enabled") {
        chrome.webRequest.onBeforeRequest.addListener(     
            function(details) {
                return {cancel: true};
            },
            {urls: blockedWebsitesUrl},
            ["blocking"]
        );
    }
    else {
        //
    }
})

But the problem is that if I refresh the extension while having the blocking enabled, when I change change it, it doesn't change until the next refresh. Can anyone help me understand how to fix this issue ?


Solution

  • Make the webRequest listener a named global function so its reference will be persistent and re-register it when the storage is changed:

    const blocker = {
      toggle: null,
      urls: [],
      listener() {
        return {cancel: true};
      },
    };
    
    function registerBlocker(toggle = blocker.toggle, urls = blocker.urls) {
      blocker.toggle = toggle;
      blocker.urls = urls;
      chrome.webRequest.onBeforeRequest.removeListener(blocker.listener);
      if (toggle === 'Enabled' && urls.length) {
        chrome.webRequest.onBeforeRequest.addListener(blocker.listener, {urls},
          ['blocking']);
      }
    },
    
    chrome.storage.sync.get(['toggle', 'urls'], data => {
      registerBlocker(data.toggle, data.urls);
    });
    
    chrome.storage.onChanged.addListener(({ toggle, urls }) => {
      if (toggle || urls) {
        registerBlocker(toggle?.newValue, urls?.newValue);
      }
    });