【问题标题】:Get original URL when redirecting via declarativeNetRequest + extensionPath通过 declarativeNetRequest + extensionPath 重定向时获取原始 URL
【发布时间】:2022-09-25 03:43:59
【问题描述】:

我需要在导航时获取 chrome 选项卡的 url,但在用户从使用 declarativeNetRequest 设置的规则重定向之前。

目前用户可以使用上下文菜单添加规则,当尝试访问被过滤的主机时,它将被重定向到内部扩展页面。


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)
}

由于用户被重定向,我目前无法删除某个 url。我的想法是在重定向发生之前获取 url,但我该怎么做呢?

    标签: javascript vue.js chrome-extension-manifest-v3 chrome-declarativenetrequest


    【解决方案1】:

    使用 regexFilter + 替换将原始 URL 附加到扩展页面 URL:

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

    现在您的扩展页面 (forbidden.html) 可以读取此 URL:

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

    您还可以从地址栏中隐藏原始 URL:

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

    如果实现https://crbug.com/1241397,希望会有更好的解决方案。

    【讨论】:

    • 我正在测试使用正则表达式实现建议解决方案的代码,目前我可以添加新规则,但问题是删除它们,因为我无法再使用这行代码了removeRuleIds: rules.map( (h, i) => hostname+'/' === h.condition.urlFilter ? h.id : null ).filter( el => el !== null )
    • 提取一个接受主机名并为 regexFilter 生成字符串的函数,然后使用它来创建和查找规则。
    • 不确定是否理解,我的想法是清除condition.regexFilter 字符串以仅包含主机但不确定如何进行
    • function makeRe(h) { return `^https?://([^/]*?[.@])?${h.replace(/\\./g, '\\.')}(:\\d+)?/.*$` } 然后在 regexFilter: makeRe(hostname) 中使用它并找到:const re = makeRe(hostname); const ids = rules.map(r => r.condition.regexFilter === re && r.id).filter(Boolean)
    • 是的,这是一个简单的slicereplace
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 1970-01-01
    • 2012-11-17
    • 2011-01-18
    • 2021-06-15
    • 2016-10-05
    • 2017-06-01
    相关资源
    最近更新 更多