浏览器扩展获取悬停YouTube嵌入iframe尺寸遇CORS,求解决方案
解决方案:捕获YouTube嵌入iframe尺寸(规避CORS限制)
核心思路
CORS限制仅针对访问iframe内部文档对象(如contentDocument/contentWindow),而iframe作为当前页面的DOM元素,其自身的尺寸属性(如offsetWidth、getBoundingClientRect())属于当前页面上下文,可直接读取无需跨域权限。
方法1:监听鼠标悬停事件直接获取尺寸
通过监听页面的mouseover事件,判断目标元素是否为YouTube嵌入iframe,直接读取其DOM尺寸属性。
// 浏览器扩展内容脚本中执行 document.addEventListener('mouseover', (e) => { const iframe = e.target; // 匹配所有YouTube嵌入域名(含标准和无cookie版本) const ytEmbedRegex = /https?:\/\/(www\.)?(youtube\.com\/embed|youtube-nocookie\.com\/embed)/i; if (iframe.tagName === 'IFRAME' && ytEmbedRegex.test(iframe.src)) { // 获取元素实际渲染尺寸 const { offsetWidth: width, offsetHeight: height } = iframe; // 或获取视口内可见尺寸(考虑滚动、缩放) const { width: viewportWidth, height: viewportHeight } = iframe.getBoundingClientRect(); // 此处可处理尺寸数据(如发送到扩展后台、弹窗显示等) console.log(`YouTube iframe 尺寸:宽${width}px,高${height}px`); console.log(`视口内可见尺寸:宽${viewportWidth}px,高${viewportHeight}px`); } });
方法2:处理动态生成的iframe
若页面存在动态加载的YouTube iframe,使用MutationObserver监听DOM变化,确保新添加的iframe也能被捕获。
// 初始化DOM变化监听器 const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { const ytEmbedRegex = /https?:\/\/(www\.)?(youtube\.com\/embed|youtube-nocookie\.com\/embed)/i; if (node.tagName === 'IFRAME' && ytEmbedRegex.test(node.src)) { // 可选:为新iframe单独绑定事件(或依赖全局mouseover事件即可) console.log('检测到新的YouTube嵌入iframe'); } }); }); }); // 配置监听范围:监听body下所有子元素变化 observer.observe(document.body, { childList: true, subtree: true });
正则表达式优化建议
之前正则未达预期,大概率是匹配范围不全,使用以下正则可覆盖所有YouTube嵌入场景:
/https?:\/\/(www\.)?(youtube\.com\/embed|youtube-nocookie\.com\/embed)/i
i标志忽略大小写- 包含
youtube.com/embed和youtube-nocookie.com/embed两种官方嵌入域名 - 匹配带/不带
www前缀的URL
关键注意事项
- 禁止访问
iframe.contentDocument或iframe.contentWindow,否则会触发CORS限制 - 确保扩展的
content_scripts配置正确,匹配目标网站的URL(如"matches": ["<all_urls>"]或特定网站) - 若需要将尺寸数据传递到扩展后台,使用
chrome.runtime.sendMessage()(Chrome)或browser.runtime.sendMessage()(Firefox)
内容的提问来源于stack exchange,提问作者Edoardo Balducci
相关产品推荐
相关产品推荐

