Manifest V3下Chrome扩展自动打开下载文件报错:User gesture required
解决Manifest V3中Chrome扩展自动打开下载文件的"User gesture required"错误
问题原因
Manifest V3对用户手势的验证逻辑比V2严格得多:chrome.downloads.open() API必须在用户主动触发的交互上下文(比如右键菜单点击、页面按钮点击等)中调用。而你当前的代码是在chrome.downloads.onChanged这个后台自动触发的事件里调用open,该事件没有用户手势上下文,因此触发报错。
另外你的代码存在一个参数名错误:chrome.downloads.onChanged的回调参数是下载变更信息对象(而非下载ID),原代码里用downloadId作为参数名会造成混淆,需要修正为changeInfo。
解决方案
通过创建通知引导用户主动触发打开操作,这样既符合Manifest V3的手势要求,又能实现下载完成后打开文件的需求。
修改后的background.js代码
chrome.contextMenus.create({ id: "reg", title: "Зарегистрировать письмо", contexts: ["link"] }); chrome.contextMenus.onClicked.addListener((info, tab) => { chrome.downloads.download({ url: info.linkUrl }); }); chrome.downloads.onChanged.addListener(function (changeInfo) { // 修正参数名,并判断状态变更为完成 if (changeInfo.state?.current === "complete") { // 创建下载完成通知 chrome.notifications.create({ type: "basic", iconUrl: "icons/icon-48.png", // 替换为你的扩展图标路径 title: "下载完成", message: "点击此通知打开已下载的文件", contextMessage: changeInfo.filename?.current || "未知文件" }, (notificationId) => { // 存储通知ID与下载ID的映射 chrome.storage.local.set({ [`notify_${notificationId}`]: changeInfo.id }); }); } }); // 监听通知点击事件,触发文件打开 chrome.notifications.onClicked.addListener((notificationId) => { chrome.storage.local.get(`notify_${notificationId}`, (result) => { const downloadId = result[`notify_${notificationId}`]; if (downloadId) { chrome.downloads.open(downloadId); // 清理存储的映射关系 chrome.storage.local.remove(`notify_${notificationId}`); } chrome.notifications.clear(notificationId); }); });
关键说明
- 用户手势合规:用户点击通知属于主动交互,此时调用
chrome.downloads.open()符合Manifest V3的手势要求,不会报错。 - 状态判断优化:使用可选链操作符
?.避免changeInfo.state或changeInfo.filename未定义时的报错。 - 存储映射关系:通过
chrome.storage.local记录通知ID和对应下载ID的关联,确保点击通知时能准确找到要打开的文件。
内容的提问来源于stack exchange,提问作者nikolay
相关产品推荐
相关产品推荐

