如何让chrome.downloads.onDeterminingFilename仅修改特定站点的下载文件名?
解决Chrome扩展中目标站点下载判断的问题
看起来你遇到的核心问题是没法通过downloadItem.referrer区分目标站点和其他站点的下载,因为目标站点返回的referrer是空字符串。别担心,我们可以换几种靠谱的思路来解决这个问题:
方案一:通过下载文件的URL直接判断
目标站点的图片URL肯定包含它的域名(或者关联的CDN域名),我们可以直接检查下载URL是否属于目标站点的域名范围,这样就能精准区分。
修改background.js的代码:
chrome.downloads.onDeterminingFilename.addListener((downloadItem, suggest) => { // 替换成你的目标站点域名(可以加多个,用||连接) const targetDomains = ["your-target-site.com", "cdn.target-site.com"]; // 检查下载URL是否包含目标域名中的任意一个 const isTargetSite = targetDomains.some(domain => downloadItem.url.includes(domain)); if (isTargetSite) { // 你的原有重命名逻辑,比如从URL提取名称或自定义命名 const fileExt = downloadItem.filename.split('.').pop(); const customName = `my-image-${Date.now()}`; // 示例:用时间戳避免重名 const saveDir = "MyDownloadedImages"; // 自定义保存目录 suggest({ filename: `${saveDir}/${customName}.${fileExt}` }); } else { // 非目标站点下载,保留原文件名,不做修改 suggest({ filename: downloadItem.filename }); } });
这个方案的好处是不需要额外配置content script,逻辑简单直接。如果目标站点的图片使用了多个CDN域名,只要把这些域名都加入targetDomains数组即可。
方案二:通过Content Script传递站点标识
如果目标站点的图片URL不包含主域名(比如用了第三方无标识的CDN),我们可以借助Content Script在页面运行的特性,主动标记来自目标站点的下载请求。
步骤1:更新manifest.json配置
添加Content Script权限,指定匹配目标站点的URL:
{ "manifest_version": 3, "name": "图片下载工具", "version": "1.0", "permissions": ["downloads", "activeTab"], "content_scripts": [ { "matches": ["*://your-target-site.com/*"], // 目标站点的URL匹配规则 "js": ["content.js"] } ], "background": { "service_worker": "background.js" } }
步骤2:编写content.js
在目标站点的页面中,监听下载触发事件(比如用户右键下载图片、点击页面内的下载按钮),向Background脚本发送标记消息:
// 示例:监听图片的右键菜单点击(可根据你的实际下载触发逻辑调整) document.addEventListener('contextmenu', (e) => { if (e.target.tagName === 'IMG') { // 记录即将下载的图片URL,告诉Background这是目标站点的下载 chrome.runtime.sendMessage({ type: "target-site-download", url: e.target.src }); // 设置10秒超时自动清除记录,避免内存占用 setTimeout(() => { chrome.runtime.sendMessage({ type: "clear-target-download", url: e.target.src }); }, 10000); } });
步骤3:修改background.js
维护一个待处理的目标站点下载URL集合,在命名时判断:
const targetDownloadUrls = new Set(); // 接收Content Script的消息 chrome.runtime.onMessage.addListener((message) => { if (message.type === "target-site-download") { targetDownloadUrls.add(message.url); } else if (message.type === "clear-target-download") { targetDownloadUrls.delete(message.url); } }); chrome.downloads.onDeterminingFilename.addListener((downloadItem, suggest) => { if (targetDownloadUrls.has(downloadItem.url)) { // 执行你的重命名逻辑 const fileExt = downloadItem.filename.split('.').pop(); const customName = `target-image-${Date.now()}`; const saveDir = "TargetSiteImages"; suggest({ filename: `${saveDir}/${customName}.${fileExt}` }); // 处理完后移除记录,避免重复匹配 targetDownloadUrls.delete(downloadItem.url); } else { suggest({ filename: downloadItem.filename }); } });
这个方案更精准,哪怕图片URL是第三方CDN的,只要是从目标站点触发的下载,都能被正确识别。需要注意的是,要根据你实际的下载触发方式调整content.js中的事件监听逻辑。
额外注意事项
- 确保manifest.json中声明了
"downloads"权限,这是处理下载命名的必要权限。 - 如果使用Manifest V3,Background脚本是Service Worker,要注意它的生命周期,不过方案二中的超时清除逻辑已经降低了数据丢失的影响。
- 测试时可以通过Chrome开发者工具的
Downloads面板查看下载请求的URL,确认判断逻辑是否生效。
内容的提问来源于stack exchange,提问作者Sam Sama
相关产品推荐
相关产品推荐

