Chrome Extension v3:大体积Uint8Array(.ts文件)下载问题求助
解决方案
针对你处理1-3GB大文件时遇到的下载问题,以下是几个可行方案:
方案1:直接在ServiceWorker中使用Chrome Downloads API(推荐)
ServiceWorker中无法使用URL.createObjectURL,但Chrome 87+版本的chrome.downloads.downloadAPI支持直接传入Blob作为body参数,无需生成URL,完美适配大文件场景:
- 确保扩展manifest.json中声明
downloads权限:
{ "permissions": ["downloads"] }
- ServiceWorker中的代码:
// 假设已拼接好目标Uint8Array const targetBlob = new Blob([uint8Array], { type: 'video/mp2t' }); chrome.downloads.download({ filename: 'merged-file.ts', // 自定义文件名 body: targetBlob, saveAs: true // 弹出保存对话框 }, (downloadId) => { if (chrome.runtime.lastError) { console.error('下载失败:', chrome.runtime.lastError); } });
这个方法跳过了数据传输和URL生成步骤,直接在后台完成下载,不会占用内容脚本的内存,也避免了消息传递的大小限制。
方案2:分块传输到内容脚本后下载
如果必须在内容脚本中触发下载,核心问题是一次性传输大文件超过Chrome消息限制,所以需要分块处理:
ServiceWorker端(发送分块)
const chunkSize = 50 * 1024 * 1024; // 50MB每块,可根据实际调整 const totalChunks = Math.ceil(uint8Array.length / chunkSize); const targetTabId = 123; // 替换为目标标签页ID // 建立持久连接 const port = chrome.tabs.connect(targetTabId, { name: 'large-file-transfer' }); // 发送初始化信息 port.postMessage({ type: 'init', totalChunks, filename: 'merged-file.ts' }); // 逐块发送数据 for (let i = 0; i < totalChunks; i++) { const start = i * chunkSize; const end = Math.min(start + chunkSize, uint8Array.length); const chunk = uint8Array.slice(start, end); port.postMessage({ type: 'chunk', index: i, data: chunk }); } // 发送完成信号 port.postMessage({ type: 'complete' });
内容脚本端(接收拼接并下载)
let fileChunks = []; let totalChunksCount = 0; let targetFilename = ''; chrome.runtime.onConnect.addListener(port => { if (port.name !== 'large-file-transfer') return; port.onMessage.addListener(msg => { switch (msg.type) { case 'init': totalChunksCount = msg.totalChunks; targetFilename = msg.filename; fileChunks = new Array(totalChunksCount); break; case 'chunk': fileChunks[msg.index] = msg.data; break; case 'complete': // 拼接所有分块 const fullLength = fileChunks.reduce((sum, chunk) => sum + chunk.length, 0); const fullUint8 = new Uint8Array(fullLength); let offset = 0; fileChunks.forEach(chunk => { fullUint8.set(chunk, offset); offset += chunk.length; }); // 生成Blob并触发下载 const blob = new Blob([fullUint8], { type: 'video/mp2t' }); const downloadUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = downloadUrl; a.download = targetFilename; document.body.appendChild(a); a.click(); document.body.remove</think_never_used_51bce0c785ca2f68081bfa7d91973934>
相关产品推荐
相关产品推荐

