Home > Software design >  chrome extension - get url before user is redirected using declarativeNetRequest
chrome extension - get url before user is redirected using declarativeNetRequest

Time:08-19

I need to get the url of a chrome tab when it's navigated but before the user is redirected from a rule that is set using declarativeNetRequest.

At the moment the user can add a rule using context menu, it will be redirected to an internal extension page when try to visit the filtered host.


chrome.contextMenus.onClicked.addListener( ( clickData) => {
    switch (clickData.menuItemId) {
        case 'blockHost':
            blockHost(clickData)
            console.log('Added host')
            break;
        case 'unblockHost':
            unblockHost(clickData)
            chrome.declarativeNetRequest.getDynamicRules( rules => console.log(rules) )
            console.log('Removed host')           
            break;
    }
})

const blockHost = async (clickData) => {
    let hostname = new URL(clickData.pageUrl).hostname
    console.log(hostname)
    let rules = await chrome.declarativeNetRequest.getDynamicRules()    
    console.log(rules.length, rules)
    let newRule = await chrome.declarativeNetRequest.updateDynamicRules({
                addRules: [{
                    id: rules.length   1,
                    action: {type: 'redirect', redirect: {extensionPath: '/forbidden.html'}},
                    condition: {urlFilter: `${hostname}/`, resourceTypes: ['main_frame', 'sub_frame']}
                }]
            });
    console.log(newRule)
    let updatedRules = await chrome.declarativeNetRequest.getDynamicRules()
    console.log('blockedhost executed', updatedRules)
}

since the user is redirected, it's impossible for me at the moment to remove a certain url. My idea is to get the url before the redirection is occur, but how I can do this?

CodePudding user response:

Use regexFilter substitution to append the original URL to extension page URL:

const hostname = 'example.com';
const EXT_PAGE = chrome.runtime.getURL('/forbidden.html');
const RULES = [{
  id: 1,
  action: {
    type: 'redirect',
    redirect: { regexSubstitution: EXT_PAGE   '#\\0' },
  },
  condition: {
    regexFilter: `^https?://([^/]*?[.@])?${hostname.replace(/\\./g, '\\.')}(:\\d )?/.*$`,
    resourceTypes: ['main_frame', 'sub_frame'],
  },
}];
chrome.declarativeNetRequest.updateDynamicRules({
  removeRuleIds: RULES.map(r => r.id),
  addRules: RULES,
});

Now your extension page (forbidden.html) can read this URL:

const origUrl = location.hash.slice(1);

You can also hide the original URL from the address bar:

history.replaceState(document.title, null, location.href.split('#')[0]);

Hopefully there'll be a better solution if https://crbug.com/1241397 is implemented.

  • Related