【问题标题】:Browser/HTML Force download of image from src="data:image/jpeg;base64..."浏览器/HTML 强制从 src="data:image/jpeg;base64..." 下载图像
【发布时间】:2012-05-15 11:31:01
【问题描述】:

我正在客户端生成一个图像,并使用 HTML 显示它,如下所示:

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

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

我怎样才能意识到浏览器正在打开一个文件保存对话框(或者只是像 chrome 或 firefox 一样将图像下载到下载文件夹中),它允许用户保存图像无需右键单击并保存像在图片上?

我更喜欢没有服务器交互的解决方案。所以我知道如果我先上传图片然后开始下载是可能的。

非常感谢!

【问题讨论】:

    标签: javascript image html browser


    【解决方案1】:

    只需将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!
    };
    

    相关文档

    【讨论】:

    • 由于某种原因,它似乎在 Chrome 19.0 beta 中被打破,但它适用于 Chrome 18 和 Firefox,所以我很好。是否可以设置文件名?
    • 无法在 data-URI 中设置文件名。即使使用canvas / Blob 导出数据,也无法设置文件名。我在答案中添加了另一种方法(我猜这个方法可以在 Chrome 19 中使用)。
    • 您是否认为第一种方法将被弃用,因为它不再适用于 chrome 19?
    • 我找不到相关的来源。顺便说一句,我还找到了this answer,它建议如何在 Chrome 中设置默认名称(仅限锚点,用户必须点击它)
    • 也找到了这个解决方案 - 现在似乎只有 chrome。感谢您的支持!
    【解决方案2】:

    您可以在 a 标签上使用下载属性...

    <a href="data:image/jpeg;base64,/9j/4AAQSkZ..." download="filename.jpg"></a>
    

    查看更多:https://developer.mozilla.org/en/HTML/element/a#attr-download

    【讨论】:

    • 动态生成图片源时如何使用该方案?我的意思是我有下载按钮,当用户点击它时,我会做一些计算,生成 base64 图像......我怎样才能强制下载?
    • 在 chrome 中我无法使用这种方法设置文件名。无论如何,下载文件的名称仍然是“下载”。这只发生在使用 data:image...
    • 我知道这是一篇旧帖子,但根据 W3Schools 网站的“下载”属性,IE、Safari 和 Opera v 不支持。w3schools.com/tags/tryit.asp?filename=tryhtml5_a_download2 实际上我用 IE 尝试过,它确实如此不工作.... :(
    • 在发表此评论时,Safari 和 IE 仍不支持 download 属性。
    • 它有 base64 长度限制,您无法使用此方法下载更大的图像。
    【解决方案3】:

    我猜 img 标签需要作为 a 标签的子标签,方法如下:

    <a download="YourFileName.jpeg" href="data:image/jpeg;base64,iVBO...CYII=">
        <img src="data:image/jpeg;base64,iVBO...CYII="></img>
    </a>
    

    <a download="YourFileName.jpeg" href="/path/to/OtherFile.jpg">
        <img src="/path/to/OtherFile.jpg"></img>
    </a>
    

    仅使用 #15 中解释的 a 标记对我来说不适用于最新版本的 Firefox 和 Chrome,但将相同的图像数据放在两个 a.href 和 img.src 标签对我有用。

    从 JavaScript 可以这样生成:

    var data = canvas.toDataURL("image/jpeg");
    
    var img = document.createElement('img');
    img.src = data;
    
    var a = document.createElement('a');
    a.setAttribute("download", "YourFileName.jpeg");
    a.setAttribute("href", data);
    a.appendChild(img);
    
    var w = open();
    w.document.title = 'Export Image';
    w.document.body.innerHTML = 'Left-click on the image to save it.';
    w.document.body.appendChild(a);
    

    【讨论】:

    • 这并不是说它需要一个 img 标签,MSDN 文档声明只能使用已经下载的资源 - 只要您在任何地方都有具有相同 data:base64 的图像,它就应该可以工作。 msdn.microsoft.com/en-us/library/cc848897.aspx -- “出于安全原因,数据 URI 仅限于下载的资源。数据 URI 不能用于导航、脚本或填充框架或 iframe 元素。”
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2014-04-15
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-05
      • 1970-01-01
      • 2015-02-04
      • 2012-09-15
      相关资源
      最近更新 更多