Manifest V3中Content Scripts未对所有YouTube匹配URL触发的问题
问题原因分析
- YouTube的SPA特性:YouTube是单页应用,切换视频时不会重新加载整个页面,你的content script仅在首次进入
/watch或/shorts页面时执行一次,后续页面切换不会触发脚本重新运行,导致新页面未应用屏蔽规则。 - 本地存储未监听变更:当你更新白名单后,已注入的content script仍使用缓存的旧白名单数据,不会主动获取新数据,必须刷新页面才能读取新规则。
解决方案
1. 重构blocker.js,实现可复用的规则判断与监听逻辑
// 获取当前视频URL function getCurrentVideoUrl() { return window.location.href; } // 检查当前URL是否在白名单中 async function isUrlWhitelisted() { const { whitelist = [] } = await chrome.storage.local.get('whitelist'); const currentUrl = getCurrentVideoUrl(); return whitelist.some(url => currentUrl.startsWith(url)); } // 核心屏蔽/放行逻辑 async function applyBlockRule() { const isWhitelisted = await isUrlWhitelisted(); // 适配YouTube的视频容器选择器 const videoContainer = document.querySelector('#player-container, #shorts-player'); if (isWhitelisted) { // 放行:恢复页面原有内容(如果之前被屏蔽) if (document.body.innerHTML.includes('该视频已被屏蔽')) { window.location.reload(); // 若之前覆盖了body,需刷新恢复原页面 } else { videoContainer?.style.removeProperty('display'); } } else { // 屏蔽:覆盖页面内容 document.body.innerHTML = '<h1 style="text-align:center;margin-top:20vh;">该视频已被屏蔽</h1>'; } } // 监听SPA页面URL变化 let lastUrl = window.location.href; new MutationObserver(() => { const currentUrl = window.location.href; if (currentUrl !== lastUrl && (currentUrl.includes('/watch?v=') || currentUrl.includes('/shorts/'))) { lastUrl = currentUrl; applyBlockRule(); } }).observe(document, { subtree: true, childList: true }); // 监听本地存储中白名单的变更 chrome.storage.onChanged.addListener((changes, area) => { if (area === 'local' && changes.whitelist) { applyBlockRule(); } }); // 页面初始加载时执行规则 document.addEventListener('DOMContentLoaded', applyBlockRule);
2. 优化content_scripts配置(可选但推荐)
添加run_at确保脚本在DOM稳定后执行,避免过早操作未加载的元素:
"content_scripts": [ { "js": ["scripts/blocker.js"], "matches": [ "https://www.youtube.com/watch?v=*", "https://www.youtube.com/shorts/*" ], "run_at": "document_idle" } ]
关键逻辑说明
- 可复用的规则函数:
applyBlockRule可以在页面导航、白名单变更、初始加载时重复调用,确保规则实时生效。 - SPA导航监听:通过MutationObserver捕获YouTube页面切换时的DOM变化,触发规则重新检查,无需依赖页面刷新。
- 实时白名单同步:
chrome.storage.onChanged监听本地存储的白名单变更,一旦白名单更新立即重新应用规则。
内容的提问来源于stack exchange,提问作者Atomnivore
相关产品推荐
相关产品推荐

