调用browser.tabs.executeScript时navigator.storage.getDirectory返回空?
我正在开发一个DevTools面板,用来检查源私有文件系统(Origin Private File System),因为Firefox LTS 115的Storage面板缺失这个功能。但通过browser.tabs.executeScript执行代码时,标签页的开发者工具控制台总是打印dir.keys() result has 0 entries,但实际上目录下是有文件的——把这段代码直接粘贴到标签页的DevTools控制台里就能正常读取到内容。
相关代码
my_devtools_panel.js
async function executeScript() { return await browser.runtime.sendMessage({ command: 'executeScript', arguments: Array.from(arguments) }); } let dir_ls = await executeScript( browser.devtools.inspectedWindow.tabId, // TODO is there any way to do this short of "<all_urls>"? { code: `(async () => { // TRY PASTING THIS BLOCK OF CODE DIRECTLY INTO THE DEV TOOLS CONSOLE INSTEAD: let dir = await navigator.storage.getDirectory(); console.debug("Browser directory: %o", dir); let dir_ls = await Array.fromAsync(dir.keys()); console.debug("dir.keys() result has %d entries: %o", dir_ls.length, dir_ls); return dir_ls; })()`, runAt: 'document_start' } ).then((result) => result[0]); debugger; document.body.appendChild(document.createTextNode(`[${dir_ls.join()}] (length: ${dir_ls.length})`));
background.js
browser.runtime.onMessage.addListener((message, sender, sendResponse) => { switch (sender.id) { case browser.runtime.id: switch (message.command) { case 'executeScript': return browser.tabs.executeScript(...message.arguments); } } });
问题原因与修复方案
核心问题:执行时机与上下文隔离
你设置了runAt: 'document_start',这会让脚本在页面初始化最早期执行——此时页面的源私有文件系统上下文还未完全初始化。另外,通过browser.tabs.executeScript注入的脚本默认在隔离环境运行,虽然能访问navigator,但无法正确关联到当前页面已初始化的存储上下文。
修复步骤:
- 改用
browser.devtools.inspectedWindow.eval()直接执行代码,这是DevTools扩展和目标页面交互的官方推荐方式,它的上下文和手动在控制台执行的完全一致,不需要通过background中转,也更高效。 - 若坚持使用
browser.tabs.executeScript,则需要移除runAt: 'document_start'(默认document_idle时机),同时确保扩展拥有<all_urls>权限。
修改后的my_devtools_panel.js代码
// 直接使用inspectedWindow.eval,无需background中转 let dir_ls = await browser.devtools.inspectedWindow.eval(`(async () => { let dir = await navigator.storage.getDirectory(); console.debug("Browser directory: %o", dir); let dir_ls = await Array.fromAsync(dir.keys()); console.debug("dir.keys() result has %d entries: %o", dir_ls.length, dir_ls); return dir_ls; })()`); debugger; document.body.appendChild(document.createTextNode(`[${dir_ls.join()}] (length: ${dir_ls.length})`));
内容的提问来源于stack exchange,提问作者JamesTheAwesomeDude
相关产品推荐
相关产品推荐

