用于重定向 YT 短片的 declarativeNetRequest 正则表达式规则在输入网址或在新选项卡中打开时起作用,但在从 YT 本身单击时不起作用

问题描述 投票:0回答:2

我正在制作一个 Chrome 扩展程序,将 youtube.com/shorts/... 重定向到 youtube.com/watch?v=...

当我在新选项卡中打开这些短链接或将它们键入时,一切正常,但当我从主页本身单击时,它们不会被重定向。

这是我的rules.json 文件:

[
    {
      "id": 1,
      "priority": 1,
      "action": { "type": "redirect", "redirect": { "regexSubstitution":"https://youtube.com/watch?v=\\1" } },
      "condition": { "regexFilter": "^.*youtube\\.com/shorts/(.*)", "resourceTypes": ["main_frame"] }
    }
  ]

这是我的manifest.json 文件:

{
    "manifest_version": 3,
    "name": "No Shorts",
    "version": "0.5",
    "description": "Play YT shorts as regular videos instead of in a separate player",
    "action": {
        "default_icon": "images/no-shorts-ico.png"
    },
    "declarative_net_request": {
        "rule_resources": [{
          "id": "ruleset_1",
          "enabled": true,
          "path": "rules.json"
        }]
      },

    "icons":{
        "16": "images/16.png",
        "48": "images/48.png",
        "128": "images/128.png"

    },
    "permissions":[ "declarativeNetRequest"],
    "host_permissions":["*://*.youtube.com/*"]

  }

我从主页点击了一个短视频,但它没有被重定向。然而,当我刷新它时,它确实被重定向了。当我单击“在新选项卡中打开”或自己输入网址时,它也会被重定向。

如果我不得不猜测,我认为这是由于类似于客户端导航的原因而发生的,但我真的不能肯定地说。有解决办法吗?

google-chrome-extension chrome-extension-manifest-v3 chrome-declarativenetrequest
2个回答
0
投票

此类内部导航使用 JS 中的history API,因此无需拦截任何网络请求。

您可以在整个 youtube 域上运行脚本并拦截

click
事件:

// page.js:

addEventListener('click', e => {
  const thumb = e.target.closest('ytd-thumbnail');
  const cmd = thumb?.__data.data.navigationEndpoint.commandMetadata.webCommandMetadata;
  if (cmd?.webPageType !== 'WEB_PAGE_TYPE_SHORTS') return;
  cmd.webPageType = 'WEB_PAGE_TYPE_WATCH';
  cmd.url = cmd.url.replace('/shorts/', '/watch?v=');
  for (const a of thumb.querySelectorAll('a'))
    a.href = a.href.replace('/shorts/', '/watch?v='); 
}, true);

//manifest.json:

  "background": { "service_worker": "bg.js" },
  "permissions": ["scripting"],
  "host_permissions": ["*://www.youtube.com/"],

//bg.js

chrome.runtime.onInstalled.addListener(async () => {
  const scripts = [{
    id: 'page',
    world: 'MAIN',
    matches: ['*://www.youtube.com/*'],
    runAt: 'document_start',
    js: ['page.js'],
  }];
  await chrome.scripting.unregisterContentScripts({ids: scripts.map(s => s.id)})
    .catch(() => {});
  await chrome.scripting.registerContentScripts(scripts);
  for (const script of scripts) {
    const execCfg = {
      target: {},
      files: script.js,
      injectImmediately: true,
      world: script.world,
    };
    for (const tab of await chrome.tabs.query({url: script.matches})) {
      execCfg.target.tabId = tab.id;
      chrome.scripting.executeScript(execCfg);
    }
  }
});

0
投票

我找到了另一种解决方法,使用

webNavigation.onHistoryStateUpdated
在历史记录更新时刷新页面。

只需确保添加权限即可

webNavigation

chrome.webNavigation.onHistoryStateUpdated.addListener(function(details) {
    chrome.tabs.reload(details.tabId);
}, { url: [{ urlMatches: 'https://www\\.youtube\\.com/shorts/(.*)$' }] });
© www.soinside.com 2019 - 2024. All rights reserved.