【问题标题】:Force Download an Image Using Javascript使用 Javascript 强制下载图像
【发布时间】:2011-10-11 10:29:35
【问题描述】:

我想知道是否有任何方法可以使用 Javascript/jQuery 制作脚本来下载(打开下载对话框)图像,这样浏览器就不会只显示它。

【问题讨论】:

标签: javascript jquery file-io force-download


【解决方案1】:

这是一个使用 HTML5 'download' 属性的简单解决方案:

document.getElementById('download').click();
<a id="download" href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download hidden></a>
如果它可以找到图片,它将下载一张猫图片。

【讨论】:

  • 我用 Firefix Developer Edition v43, Firefox v39, Microsost Edge, Internet Explorer v11 测试过,页面显示图片,没有出现下载对话框
  • 检查这个caniuse.com/#feat=download,请注意虽然据说它应该与FF 39一起工作,但我用图像测试过它并显示在浏览器中
  • 解决所有下载问题的简单解决方案!程序员讨厌他!
  • safari 不支持下载属性
【解决方案2】:

您需要为此使用服务器端脚本。 Search on stackoverflow.

或者,您的服务器可能允许您通过配置动态更改标头。

带有 mod_headers 的 Apache 解决方案

将可下载的图像放在一个目录中。在此目录中,创建一个 .htaccess 文件,其内容如下:

SetEnvIf Request_URI "([^/]+\.jpg)$" REQUESTED_IMAGE_BASENAME=$1
SetEnvIf Request_URI "([^/]+\.png)$" REQUESTED_IMAGE_BASENAME=$1
Header set Content-Disposition "attachment; filename=\"%{REQUESTED_IMAGE_BASENAME}e\"" env=REQUESTED_IMAGE_BASENAME

测试请求:

HEAD /test/Water%20lilies.jpg HTTP/1.1
Host: localhost

测试响应:

HTTP/1.1 200 OK
Date: Sat, 23 Jul 2011 09:03:52 GMT
Server: Apache/2.2.17 (Win32)
Last-Modified: Thu, 23 Aug 2001 14:00:00 GMT
ETag: "26000000017df3-14752-38c32e813d800"
Accept-Ranges: bytes
Content-Length: 83794
Content-Disposition: attachment; filename="Water lilies.jpg"
Content-Type: image/jpeg

HTML5解决方案

您可以use the HTML5 download attribute on anchors:

<p>Example 1<br>
   <a href="http://dummyimage.com/600x400/000/fff.png" download>Download this image</a></p>

<p>Example 2<br>
   <a href="http://dummyimage.com/600x400/000/fff.png" download="alternate-filename.png"><img
       src="http://dummyimage.com/150x100/000/fff.png"></a></p>

【讨论】:

  • HTML 5 解决方案简直太棒了
  • 下载属性没有被广泛支持。除非您计划为不受支持的浏览器实现回退,否则您可能不应该使用它。 caniuse.com/download
  • 不是现在,而是未来几年。
  • 截至 2015 年仅 safari 和 IE 不支持 download attribute.
  • 截至 2016 年的 safari 仍然不支持它。我不知道 IE,但谁在乎 IE...
【解决方案3】:

我想出了纯 JavaScript 方式来强制下载图片,但有以下限制:

  1. 使用 HTML5,因此在 IE9 之前的 IE 浏览器中根本无法使用。
  2. 由于 URL 长度限制,在 IE(甚至 9 个)中仅限于非常小的图像。
  3. 无法在代码中确定图像名称(保存到机器时),在 Chrome 中,它只是“下载”而没有扩展名,而在 Firefox 中,它看起来像带有“.part”扩展名的乱码字符串 -无论哪种方式,用户都必须重命名文件以使其可用。
  4. 只能下载同域的图片 - 同源策略。

上述限制(尤其是第三个限制)或多或少使这个无用,但“核心”想法正在起作用,希望在未来的某个时候可以确定文件名那么它将变得更加有用。

代码如下:

function DownloadImage(imageURL) {
    var oImage = document.getElementById(imageURL);
    var canvas = document.createElement("canvas");
    document.body.appendChild(canvas);
    if (typeof canvas.getContext == "undefined" || !canvas.getContext) {
        alert("browser does not support this action, sorry");
        return false;
    }

    try {
        var context = canvas.getContext("2d");
        var width = oImage.width;
        var height = oImage.height;
        canvas.width = width;
        canvas.height = height;
        canvas.style.width = width + "px";
        canvas.style.height = height + "px";
        context.drawImage(oImage, 0, 0, width, height);
        var rawImageData = canvas.toDataURL("image/png;base64");
        rawImageData = rawImageData.replace("image/png", "image/octet-stream");
        document.location.href = rawImageData;
        document.body.removeChild(canvas);
    }
    catch (err) {
        document.body.removeChild(canvas);
        alert("Sorry, can't download");
    }

    return true;
}

如您所见,诀窍是将图像绘制到canvas 对象中,获取图像的原始二进制数据,然后通过使用image/octet-stream mime 类型并更改浏览器位置来强制下载。

用法示例如下。

HTML:

<image id="myimage" src="Penguins.jpg" />
<button type="btnDownload" rel="myimage">Download</button>

JavaScript:

window.onload = function() {
    var arrButtons = document.getElementsByTagName("button");
    for (var i = 0; i < arrButtons.length; i++) {
        var oButton = arrButtons[i];
        var sRelatedImage = oButton.getAttribute("rel");
        if (sRelatedImage && sRelatedImage.length > 0) {
            oButton.onclick = function() {
                HandleRelatedImage(this, sRelatedImage);
            }
        }
    }
};

function HandleRelatedImage(oButton, sRelatedImage) {
    var oImage = document.getElementById(sRelatedImage);
    if (!oImage) {
        alert("related image '" + sRelatedImage + "' does not exist");
        return false;
    }

    return DownloadImage(sRelatedImage);
}

这允许通过将按钮的 rel 属性分配给图像 ID 来将下载按钮“附加”到每个现有图像 - 代码将完成剩下的工作并附加实际的点击事件。

由于相同的来源政策无法在 jsFiddle 发布实时示例 - 他们使用“沙盒”域来执行脚本。

【讨论】:

    【解决方案4】:

    这是完全可能的。只需将图像编码为 Base64,然后使用 data:image/jpg,Base64,... 样式的 url 执行 window.open

    【讨论】:

    • 这让我在新标签页上打开图片。
    猜你喜欢
    • 1970-01-01
    • 2011-08-04
    • 2018-10-20
    • 2015-12-14
    • 1970-01-01
    • 2012-08-16
    • 2011-05-12
    • 2010-12-28
    相关资源
    最近更新 更多