Firefox WebExtensions:如何获取页面已获取的JSON对象(无需重新下载)
可行方案(Firefox 环境)
1. 注入内容脚本挂钩 fetch 和 XMLHttpRequest
这是最通用的方案,通过在页面加载前注入脚本,拦截并缓存所有JSON请求的响应,后续无需重新下载即可直接访问。
实现步骤:
- 在扩展的
manifest.json中配置content_scripts,设置run_at: "document_start",确保脚本优先于页面其他JS执行。 - 重写
fetch和XMLHttpRequest方法,拦截JSON类型的响应,解析后存储到全局变量中。
示例代码:
// 内容脚本中执行 (function() { // 存储已获取的JSON,以请求URL为键 window._cachedJson = {}; // 拦截fetch请求 const originalFetch = window.fetch; window.fetch = async function(...args) { const response = await originalFetch(...args); if (response.headers.get('content-type')?.includes('application/json')) { // 克隆响应,避免原响应被页面消耗 const clonedRes = response.clone(); try { const jsonData = await clonedRes.json(); window._cachedJson[args[0]] = jsonData; } catch (e) { // 忽略非标准JSON格式的响应 } } return response; }; // 拦截XMLHttpRequest请求 const originalXHR = window.XMLHttpRequest; window.XMLHttpRequest = function() { const xhr = new originalXHR(); const originalOnLoad = xhr.onload; xhr.onload = function() { if (xhr.getResponseHeader('content-type')?.includes('application/json')) { try { const jsonData = JSON.parse(xhr.responseText); window._cachedJson[xhr.responseURL] = jsonData; } catch (e) {} } originalOnLoad?.call(this); }; return xhr; }; })();
页面加载完成后,可通过内容脚本或开发者工具访问window._cachedJson,直接获取已缓存的JSON数据。
2. 利用 Firefox DevTools API(仅适用于开发者工具扩展)
如果是开发Firefox开发者工具扩展,可直接通过devtools.networkAPI读取浏览器缓存的响应,无需重新请求。
示例代码:
// 开发者工具扩展中执行 browser.devtools.network.onRequestFinished.addListener((request) => { if (request.response.content.mimeType.includes('application/json')) { request.getContent((content) => { try { const jsonData = JSON.parse(content); // 处理获取到的JSON数据 console.log('缓存的JSON:', jsonData); } catch (e) {} }); } });
注意:该方案仅适用于开发者工具类扩展,普通网页扩展无法使用。
3. 直接读取页面全局变量(针对特定网站)
如果目标页面本身将JSON数据挂载到了window等全局可访问的变量中(比如window.pageData = {...}),可直接通过内容脚本读取该变量。但这种方式依赖页面实现,通用性较差。
额外注意:
- 内容脚本与页面上下文隔离,若需在扩展后台脚本中访问缓存数据,可通过
browser.runtime.sendMessage或browser.storage.local传递。 - 挂钩请求方法时,务必克隆响应,避免干扰页面原有逻辑。
- 扩展需在
manifest.json中声明对应权限,比如content_scripts需指定匹配网站,开发者工具扩展需声明"devtools": true。
内容的提问来源于stack exchange,提问作者bangers-and-mash
相关产品推荐
相关产品推荐

