Chrome扩展实时替换Google Meet人脸图像的代码报错求助
Google Meet人脸替换Chrome扩展(Manifest V3)问题修复方案
核心问题梳理
https://meet.google.com/域名下错误引用扩展内部JS文件,导致加载失败- loader.js中
document.body.insertBefore执行时DOM元素未就绪,引发报错 - 违反CSP(内容安全策略):禁止加载外部脚本、禁止内联脚本执行、Promise未捕获异常
分步修复方案
1. 修正资源引用路径,解决URL配置异常
问题原因:loader.js中直接使用脚本文件名作为src,浏览器会将其解析为当前页面域名(meet.google.com)下的资源,而非扩展内部文件。
修复代码(修改loader.js):
将loadScript函数中的script.src = src改为使用chrome.runtime.getURL获取扩展资源的绝对路径:
function loadScript(src) { return new Promise((resolve, reject) => { const script = document.createElement('script') // 修正:使用chrome.runtime.getURL获取扩展内部资源路径 script.src = chrome.runtime.getURL(src) script.onload = () => { console.log(`loaded: ${src}`) resolve() } script.onerror = (e) => reject(e) // 改用document.head插入,避免body未就绪问题 document.head.appendChild(script) }) }
2. 修复DOM操作报错,避免元素未就绪
问题原因:window.load事件触发时,document.body可能尚未完成渲染,直接调用insertBefore会引发DOM异常。
修复方式:
- 改用
document.head.appendChild替代document.body.insertBefore,head元素在页面加载早期就已存在 - 移除
loadLocalScript函数的内联脚本逻辑,统一使用外部脚本加载方式(解决CSP内联禁止问题)
修改后的loadLocalScript和load函数:
// 移除原内联脚本逻辑,统一用loadScript加载外部资源 async function loadLocalScript(path) { await loadScript(path) } async function load() { await loadLocalScript("lmMarkImg.js") await loadScript("tf-core.js") await loadScript("tf-converter.js") await loadScript("tf-backend-webgl.js") await loadScript("face-landmarks-detection.js") await loadLocalScript("main.js") } // 改用DOMContentLoaded事件,确保DOM就绪后执行 document.addEventListener('DOMContentLoaded', async (evt) => { await load().catch(err => console.error('加载脚本失败:', err)) })
3. 解决CSP内容安全策略冲突
问题原因:
- Manifest V3默认禁止内联脚本执行,原
loadLocalScript的内联注入方式违反规则 - 扩展内部资源未声明为
web_accessible_resources,无法被页面上下文访问
修复步骤:
(1)更新manifest.json,声明可访问资源并调整内容脚本配置
{ "manifest_version": 3, "name": "Meet Face Hack Extension", "version": "0.0.1", "description": "Meet hack", "host_permissions": [ "https://meet.google.com/*" ], "content_scripts": [ { "js": ["loader.js"], "matches": ["https://meet.google.com/*"], "run_at": "document_start" } ], // 新增:声明允许页面上下文访问的扩展资源 "web_accessible_resources": [ { "resources": ["lmMarkImg.js", "tf-core.js", "tf-converter.js", "tf-backend-webgl.js", "face-landmarks-detection.js", "main.js"], "matches": ["https://meet.google.com/*"] } ] }
- 内容脚本仅保留
loader.js,其他脚本通过动态注入加载到页面上下文 - 新增
web_accessible_resources字段,允许Meet页面访问扩展内部的JS文件
(2)移除内联脚本逻辑,避免CSP报错
彻底删除原loadLocalScript中的内联脚本生成代码,统一使用外部脚本加载(已在步骤2中完成)。
4. 捕获Promise异常,解决未捕获错误
问题原因:loader.js中load函数的Promise未添加错误捕获,一旦加载失败会抛出未捕获异常。
修复方式:
在DOMContentLoaded事件监听中添加catch块捕获错误:
document.addEventListener('DOMContentLoaded', async (evt) => { await load().catch(err => { console.error('脚本加载失败:', err) // 可添加错误提示逻辑 }) })
额外优化建议
- 移除extension.sh中对main.js的
sed替换操作,因为现在通过chrome.runtime.getURL加载资源,无需替换原URL - 检查face-kandmarks-detection.js的文件名拼写(应为face-landmarks-detection.js),避免加载错误
内容的提问来源于stack exchange,提问作者moca
相关产品推荐
相关产品推荐

