Manifest V3背景服务Worker中Blob文件下载方法求助
解决Manifest V3后台Service Worker中Blob下载问题
由于后台Service Worker没有DOM环境,无法直接触发下载动作,需要将Blob传递到有DOM的上下文(内容脚本、临时页面)中完成下载,以下是两种可行方案:
方案一:借助内容脚本实现下载
1. 后台Service Worker中的download函数
async function download(blobObj) { // 获取当前激活标签页 const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!activeTab?.id) return; // 将Blob传递给内容脚本,使用Transferable转移所有权提升性能 chrome.tabs.sendMessage(activeTab.id, { type: 'TRIGGER_DOWNLOAD', blob: blobObj }, { transfer: [blobObj] } ); }
2. 内容脚本代码(需在manifest中配置content_scripts)
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg.type !== 'TRIGGER_DOWNLOAD') return; const blob = msg.blob; // 创建下载链接与触发元素 const downloadUrl = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = downloadUrl; link.download = '自定义文件名.png'; // 替换为实际文件名 document.body.appendChild(link); link.click(); // 清理资源 setTimeout(() => { document.body.removeChild(link); URL.revokeObjectURL(downloadUrl); }, 100); sendResponse({ success: true }); });
3. Manifest配置示例
{ "content_scripts": [ { "matches": ["<all_urls>"], // 根据业务需求调整匹配规则 "js": ["content-script.js"] } ] }
方案二:创建临时页面处理下载(无内容脚本场景)
1. 后台Service Worker中的download函数
async function download(blobObj) { // 创建临时下载页面 const tempTab = await chrome.tabs.create({ url: chrome.runtime.getURL('temp-download.html'), active: false }); // 监听页面加载完成事件 const loadListener = (tabId, info) => { if (tabId === tempTab.id && info.status === 'complete') { chrome.tabs.onUpdated.removeListener(loadListener); // 传递Blob到临时页面 chrome.tabs.sendMessage(tempTab.id, { type: 'TRIGGER_DOWNLOAD', blob: blobObj }, { transfer: [blobObj] }, () => chrome.tabs.remove(tempTab.id) // 下载完成后关闭临时页 ); } }; chrome.tabs.onUpdated.addListener(loadListener); }
2. 临时页面temp-download.html代码
<!DOCTYPE html> <html> <body> <script> chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg.type !== 'TRIGGER_DOWNLOAD') return; const blob = msg.blob; const downloadUrl = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = downloadUrl; link.download = '自定义文件名.png'; document.body.appendChild(link); link.click(); setTimeout(() => { URL.revokeObjectURL(downloadUrl); sendResponse({ success: true }); }, 100); return true; // 保持消息通道开放至sendResponse调用 }); </script> </body> </html>
3. Manifest配置补充
{ "web_accessible_resources": [ { "resources": ["temp-download.html"], "matches": ["<all_urls>"] } ] }
内容的提问来源于stack exchange,提问作者Mayank Maurya
相关产品推荐
相关产品推荐

