如何在用户脚本环境下让Firefox/Chrome按指定名称下载跨域图片?
解决跨域图片下载时
download属性失效的问题 我之前在给图片板写用户脚本时,也碰到过完全一样的痛点——跨域图片的download属性在Chrome和Firefox里根本不生效,要么忽略自定义文件名,要么直接无视这个属性。试过Blob代理、Canvas转存都有各种问题,后来终于找到几个靠谱的低成本方案,分享给你:
最优方案:利用用户脚本权限直接获取原文件并触发下载
用户脚本(比如Tampermonkey/Greasemonkey)有特殊的跨域请求权限,完全可以绕过浏览器的CORS限制,直接获取图片的原始二进制数据,再通过Blob URL触发下载,这样download属性就能正常生效,还不会损坏图片质量。
具体实现步骤
- 监听页面上所有带
download属性的下载链接点击事件,阻止默认跳转 - 用用户脚本专属的
GM_xmlhttpRequestAPI请求图片的完整URL,获取Blob格式的原始数据 - 基于Blob创建同域的Object URL,用这个URL创建临时下载链接,指定想要的文件名
- 触发临时链接的点击事件,完成下载后清理资源
代码示例
// ==UserScript== // @name 图片板友好下载脚本 // @namespace http://tampermonkey.net/ // @version 0.1 // @description 为跨域图片添加正确的保存文件名 // @author Your Name // @match https://www.example.com/* // 替换为目标图片板域名 // @connect static.example.com // 替换为静态资源域名 // @grant GM_xmlhttpRequest // ==/UserScript== (function() { 'use strict'; // 监听页面点击事件 document.addEventListener('click', handleDownloadClick); function handleDownloadClick(e) { // 找到被点击的下载链接 const downloadLink = e.target.closest('a[download]'); if (!downloadLink) return; // 阻止默认的跨域下载行为 e.preventDefault(); const imageUrl = downloadLink.href; const targetFilename = downloadLink.download; // 用GM_xmlhttpRequest跨域获取图片Blob数据 GM_xmlhttpRequest({ method: 'GET', url: imageUrl, responseType: 'blob', onload: function(res) { if (res.status !== 200) { alert('图片下载失败,请重试'); return; } // 创建Blob URL const blobUrl = URL.createObjectURL(res.response); // 创建临时下载链接 const tempLink = document.createElement('a'); tempLink.href = blobUrl; tempLink.download = targetFilename; // 触发下载 document.body.appendChild(tempLink); tempLink.click(); document.body.removeChild(tempLink); // 清理Blob URL,释放资源 setTimeout(() => URL.revokeObjectURL(blobUrl), 100); }, onerror: function() { alert('请求图片时出错,请检查网络'); } }); } })();
方案优势
- 完全保留图片原始质量,不会像Canvas方案那样出现JPEG二次压缩、透明通道丢失等问题
- 绕过CORS限制,无需配置服务器或本地代理
- 生成的Blob URL属于当前页面同域,浏览器会正常识别
download属性,Chrome和Firefox都能完美显示建议文件名 - 实现成本低,只需要几行代码,利用用户脚本的原生API就能完成
注意事项
- 必须在用户脚本的元数据中添加
@connect static.example.com,授权脚本向静态资源域名发起跨域请求 - 不同的用户脚本管理器(比如Tampermonkey和Greasemonkey)API细节可能略有差异,上面的代码基于Tampermonkey测试通过
- 如果图片板有反爬机制,可能需要在请求中添加额外的请求头(比如
Referer),可以在GM_xmlhttpRequest的headers参数中配置
内容的提问来源于stack exchange,提问作者Athari
相关产品推荐
相关产品推荐

