我正在制作一个 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/*"]
}
我从主页点击了一个短视频,但它没有被重定向。然而,当我刷新它时,它确实被重定向了。当我单击“在新选项卡中打开”或自己输入网址时,它也会被重定向。
如果我不得不猜测,我认为这是由于类似于客户端导航的原因而发生的,但我真的不能肯定地说。有解决办法吗?
此类内部导航使用 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);
}
}
});
我找到了另一种解决方法,使用
webNavigation.onHistoryStateUpdated
在历史记录更新时刷新页面。
只需确保添加权限即可
webNavigation
chrome.webNavigation.onHistoryStateUpdated.addListener(function(details) {
chrome.tabs.reload(details.tabId);
}, { url: [{ urlMatches: 'https://www\\.youtube\\.com/shorts/(.*)$' }] });