Chrome扩展复制PNG到剪贴板时遇Blob解码DOMException错误
错误原因分析与修正方案
核心错误点
1. 前台代码:异步操作顺序完全错误
chrome.runtime.sendMessage是异步执行的,回调函数里才会给blob赋值,但你在调用sendMessage后立刻执行了创建File和剪贴板写入的代码——这时候blob还是初始的空字符串,用空字符串生成的File根本不是有效的PNG文件,自然会触发解码失败的错误。
2. Background.js:两处关键错误
- 参数解析错误:你错误地把message里的
url(字符串类型)当成对象去读取url.json和url.blob,这两个值都是undefined,转成布尔值后全为false,导致fetchUrl直接返回"ERROR",根本没发起有效的Blob请求。正确的参数应该取自message.json和message.blob。 - 异步响应处理错误:
fetchUrl是async函数,返回的是Promise对象,直接用sendResponse传递Promise是无效的,必须等待Promise完成后再发送实际结果,同时要在监听器里返回true声明会异步响应。
修正后的代码
前台JS代码
// 把剪贴板操作放在sendMessage的回调里,确保拿到有效Blob后再执行 chrome.runtime.sendMessage( {request: "fetch", url: board_url, json: "false", blob: "true"}, async function(bblob) { if (!bblob || bblob === "ERROR") { console.error("获取图片Blob失败"); return; } try { // 无需转File,ClipboardItem直接支持Blob类型 await navigator.clipboard.write([ new ClipboardItem({ 'image/png': bblob }) ]); console.log("图片复制到剪贴板成功"); } catch (error) { console.error(error); } } );
Background.js代码
async function fetchUrl(url, json, blob) { try { const response = await fetch(url); if (!response.ok) throw new Error(`请求失败:${response.status}`); if (json && !blob) { return await response.json(); } else if (blob && !json) { return await response.blob(); } else { return "ERROR"; } } catch (err) { console.error(err); return "ERROR"; } } chrome.runtime.onMessage.addListener(async function(message, sender, sendResponse) { if (message.request === "fetch") { const url = message.url; // 正确解析message里的参数(注意原参数是字符串"true"/"false") const json = message.json === "true"; const blob = message.blob === "true"; const result = await fetchUrl(url, json, blob); sendResponse(result); } // 返回true告知Chrome会异步调用sendResponse return true; });
额外注意事项
- 确保你的扩展
manifest.json中配置了目标board_url对应的host_permissions,否则fetch请求会被跨域规则拦截。 - 无需将Blob转为File,ClipboardItem原生支持Blob类型,转File属于多余操作,可能引入额外问题。
内容的提问来源于stack exchange,提问作者The Amateur Coder
相关产品推荐
相关产品推荐

