You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用browser.tabs.executeScript时navigator.storage.getDirectory返回空?

问题:DevTools面板调用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,但无法正确关联到当前页面已初始化的存储上下文。

修复步骤:

  1. 改用browser.devtools.inspectedWindow.eval()直接执行代码,这是DevTools扩展和目标页面交互的官方推荐方式,它的上下文和手动在控制台执行的完全一致,不需要通过background中转,也更高效。
  2. 若坚持使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:23:13