Search code examples
jsonapigoogle-chrome-extensiongoogle-apichrome-declarativenetrequest

Exclude specific URLs from chrome.declarativeNetRequest redirect?


I've been trying to program a chrome extension that redirects the user to a specific YouTube video whenever they access YouTube. The problem is that currently, typing in 'youtube.com' results in 'ERR_TOO_MANY_REDIRECTS' instead of the specific video.

manifest.json:

{
    "manifest_version": 3,
    "name": "Redirectory",
    "description": "Redirect YouTube links",
    "version": "1.0",
    "declarative_net_request": {
        "rule_resources" :[{
            "id": "ruleset_1",
            "enabled": true,
            "path": "rules.json"
        }]
    },
    "permissions": [
        "declarativeNetRequestWithHostAccess",
        "declarativeNetRequestFeedback"
    ],
    "host_permissions": [
        "https://www.youtube.com/*"
    ]
}

rules.json:

[
    {
        "id": 1,
        "priority": 1,
        "action": { 
            "type": "redirect",
            "redirect": {
                "url": "https://youtu.be/tyu92s0cuCk"
            } 
        },
        "condition": {
            "urlFilter": "https://www.youtube.com/*",
            "resourceTypes": [
                "csp_report", "font", "image", "main_frame", "media", "object", 
                "other", "ping", "script", "stylesheet", "sub_frame", "webbundle", 
                "websocket", "webtransport", "xmlhttprequest"
            ],
            "excludedInitiatorDomains": [ 
                "https://youtu.be/tyu92s0cuCk.com",
                "https://www.youtube.com/watch?v=tyu92s0cuCk"
            ]
        }
    }
]

I believe the problem arises from the condition being any 'youtube.com' video, but it redirects to another youtube video. As a result, it tries redirecting THAT youtube video since it also begins with 'https://www.youtube.com/'.

I feel that being able to exclude the 'https://youtu.be/tyu92s0cuCk' URL from the redirect as a whole would solve the issue? Though I'm not 100% sure.

I added 'excludedInitiatorDomains' in a desperate bid to exclude that specific URL, so it should be noted that it has the same issue with or without that bit. Is there something that is essentially 'excludedFullUrl'? I couldn't find anything similar in the documentation.

Also, I am pretty new to programming so I'd appreciate it if you went a little more in-depth / explanatory in your answers. Thank you in advance!


Solution

  • The problem is your use of a short URL youtu.be: the browser redirects to it, then this server redirects back to www.youtube.com, and your rule is applied again. Apparently, declarativeNetRequest can't prevent recursion when an intermediate redirect is involved.

    The solution is to use the full URL in redirect:

    [{
      "id": 1,
      "priority": 1,
      "action": {
        "type": "redirect",
        "redirect": {
          "url": "https://www.youtube.com/watch?v=tyu92s0cuCk"
        }
      },
      "condition": {
        "urlFilter": "https://www.youtube.com/*",
        "resourceTypes": ["main_frame"]
      }
    }]
    

    Note though this won't help with links inside the site because YouTube uses "soft navigation" (the same page is shown but its contents and the address are changed through JS). You can intercept it via navigation.onnavigate event in your content script that matches the entire site e.g. https://www.youtube.com/*.