Chrome MV3扩展注入脚本中navigator.MediaDevices返回undefined的问题
我正在开发一款Chrome扩展,用来录制当前标签页的视频。脚本注入器运行正常,但尝试获取navigator.MediaDevices时返回undefined。按文档说明,这种情况一般出现在不安全上下文,但我在HTTPS标签页和localhost环境测试都是同样的结果。推测是Chrome MV3扩展的特有问题,调整manifest权限后也没解决。
注入脚本代码
async function contScript(){ const res = await execOnCurrTab(() => { const nav = navigator; const MD = nav.MediaDevices; const MS = MD.getDisplayMedia(); }); } function execOnCurrTab(callback){ return new Promise(function(resolve){ chrome.tabs.query({ active: true }, function (tabs) { let tab = tabs[0]; chrome.scripting.executeScript( { target: { tabId: tab.id }, function: callback, args: [tab.title], }, (injectionResults) => { const injRes = injectionResults[0].result; console.log(injRes) testObj = { 'res' : injRes } resolve(injRes); } ); }); }); }
Manifest权限配置
"permissions": [ "desktopCapture", "activeTab", "storage", "notifications", "alarms", "scripting" ],
问题原因及解决办法
- 上下文限制:Chrome MV3中,内容脚本无法直接调用
navigator.MediaDevices.getDisplayMedia,这类需要用户授权的媒体捕获API必须通过扩展后台发起请求。 - 正确实现流程:
- 在后台服务工作者中调用
chrome.desktopCapture.chooseDesktopMedia获取媒体流ID:// service-worker.js chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.type === 'startCapture') { chrome.desktopCapture.chooseDesktopMedia( ['tab'], sender.tab, (streamId) => { sendResponse(streamId ? {streamId} : {error: '用户取消捕获'}); } ); return true; // 保持消息通道开放以处理异步响应 } }); - 修改内容脚本,改为向后台请求流ID后再获取媒体流:
async function contScript(){ const response = await chrome.runtime.sendMessage({type: 'startCapture'}); if (response.streamId) { const mediaStream = await navigator.mediaDevices.getUserMedia({ video: { mandatory: { chromeMediaSource: 'desktop', chromeMediaSourceId: response.streamId, maxWidth: screen.width, maxHeight: screen.height } } }); // 这里可以添加录制逻辑,比如使用MediaRecorder } } - 在manifest中注册后台服务工作者:
"background": { "service_worker": "service-worker.js" },
- 在后台服务工作者中调用
- 权限说明:现有
desktopCapture和activeTab权限足够,无需额外添加,但要确保扩展安装时权限申请正常。
内容的提问来源于stack exchange,提问作者Corvus Corax
相关产品推荐
相关产品推荐

