不,似乎没有任何事件让您知props有该download
属性的锚点是否确实成功下载了资源。
但是,您面临的限制似乎只与这种情况有关:<a>
具有download
属性的锚元素。
浏览器可以处理更长的 dataURI(我认为在大多数浏览器中,限制与字符串长度的限制相同)。例如,它可以将其加载到<img>
元素,更重要的是,在您的情况下,它可以处理 dataURI 字符串。
这很重要,因为它允许您将此 dataURI 转换为 blob,然后object URL
从该 blob创建一个。object URL
的 URI 很小,并且在具有download
属性的锚点中不会遇到这种长度限制。
因此,在您的情况下,最好的canvas.toBlob
方法可能是直接使用该方法(mdn 上提供了一个 polyfill),并将object URL
的 URI 作为href
您的锚点的 URI传递。
var img = new Image();
img.crossOrigin = "anonymous";
img.onload = function(){
var ctx = document.createElement('canvas').getContext('2d');
ctx.canvas.width = this.width*10;
ctx.canvas.height = this.height*10;
ctx.drawImage(this,0,0,ctx.canvas.width, ctx.canvas.height);
// convert our canvas to a png blob
// (for type use the second parameter, third is for quality if type is image/jpeg or image/webp)
ctx.canvas.toBlob(function(blob){
myAnchor.href = URL.createObjectURL(blob);
});
// since we are dealing with use files, we absolutely need to revoke the ObjectURL as soon as possible
var revokeURL = function(){
// but we have to wait that the browser actually prepared the file to download
requestAnimationFrame(function(){
// we've waited one frame, it's seems to be enough
URL.revokeObjectURL(this.href);
this.href=null;
});
this.removeEventListener('click', revokeURL);
};
myAnchor.addEventListener('click', revokeURL);
};
img.src = 'http://lorempixel.com/200/200/';
<a id="myAnchor" download="anAwesomeImage.png">download</a>
[ Live Demo ] (因为download
SE-Snippets 中的某些 UA 阻止了属性)
但请注意,即使 的字符串表示 (URI)object URL
很短,它实际上也会占用浏览器内存中文件的大小,因此直到您硬刷新页面(清除缓存)或关闭您创建的选项卡这个对象的 URL。所以你绝对需要打电话URL.revokeObjectURL()
来清理这个空间。
但是,由于没有事件可以知道下载是否真的成功,因此您会遇到该onclick
事件,该事件将在文件下载发生之前触发。从我的测试来看,等待单帧requestAnimationFrame
就足够了,但我可能错了。
对于那些带着其他来源而不是画布来获取 dataURI 的人,SO 中已经有很多关于将 dataURI 转换为 blob 的帖子,您可以查看上面提供的 mdn polyfill,他们正在这样做也。