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.