从src="data:image/jpeg;base64..."强制下载浏览器/HTML中的图像

90

我在客户端生成一张图片,然后通过HTML显示它,代码如下:

<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgM...."/>

我想提供下载生成图片的可能性。

如何实现浏览器打开文件保存对话框(或者像Chrome或Firefox一样将图片下载到下载文件夹中),使用户可以保存图片而不需要右键单击并选择“另存为”?

我更喜欢没有服务器交互的解决方案。因此,我知道如果我首先上传图片,然后再开始下载,这是可行的。

非常感谢!

4个回答

125

只需将image/jpeg替换为application/octet-stream。客户端将无法将URL识别为可内联资源,并提示下载对话框。

一个简单的JavaScript解决方案如下:

//var img = reference to image
var url = img.src.replace(/^data:image\/[^;]+/, 'data:application/octet-stream');
window.open(url);
// Or perhaps: location.href = url;
// Or even setting the location of an <iframe> element, 

另一种方法是使用 blob: URI:

var img = document.images[0];
img.onclick = function() {
    // atob to base64_decode the data-URI
    var image_data = atob(img.src.split(',')[1]);
    // Use typed arrays to convert the binary data to a Blob
    var arraybuffer = new ArrayBuffer(image_data.length);
    var view = new Uint8Array(arraybuffer);
    for (var i=0; i<image_data.length; i++) {
        view[i] = image_data.charCodeAt(i) & 0xff;
    }
    try {
        // This is the recommended method:
        var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});
    } catch (e) {
        // The BlobBuilder API has been deprecated in favour of Blob, but older
        // browsers don't know about the Blob constructor
        // IE10 also supports BlobBuilder, but since the `Blob` constructor
        //  also works, there's no need to add `MSBlobBuilder`.
        var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder);
        bb.append(arraybuffer);
        var blob = bb.getBlob('application/octet-stream'); // <-- Here's the Blob
    }

    // Use the URL object to create a temporary URL
    var url = (window.webkitURL || window.URL).createObjectURL(blob);
    location.href = url; // <-- Download!
};

相关文档


1
由于某种原因,它在Chrome 19.0 beta版本中似乎出现了问题,但在Chrome 18和Firefox上运行正常,所以我没事。是否有可能设置文件名? - alex
2
你认为第一种方法会过时吗?因为它在Chrome 19中不再起作用了。 - alex
1
我无法找到相关的来源。顺便提一下,我也找到了这个答案,它建议如何在 Chrome 中设置默认名称(只限锚点,用户必须单击它)。 - Rob W
如果您需要定义文件名,您也可以尝试设置HTTP头:<a href="data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20image.png;base64,iVBORw0KGgoAAAA...."> - Nippey
@Nippey 我测试了 Opera 9 - 15,它们都不支持 headers 标志。好消息是,Opera 15 基于 Chromium,因此它也支持 "download" 属性。 - Rob W
显示剩余12条评论

102

1
当我动态生成图像源时,我该如何使用此解决方案?我的意思是,我有一个下载按钮,当用户点击它时,我会进行一些计算,生成base64图像,然后...我该如何强制下载? - Mikhail
5
我知道这是一篇旧帖子,但根据W3Schools网站,“download”属性不受IE、Safari和Opera v. < 12的支持。实际上,我在IE中尝试了一下,它并不起作用……:( - Mirko Lugano
6
截至该评论发布时,download属性仍未在Safari和IE中得到支持。 - TheCarver
@BruceAldridge 另一个问题。如果我的图片只是一个 URL,我该如何创建它? - jofftiquez
2
它有Base64长度限制,您不能使用此方法下载较大的图像。 - Kiran Chenna
显示剩余4条评论


5

请查看FileSaver.js。它提供了一个方便的saveAs函数,可以处理大多数浏览器特定的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接