使用Javascript强制下载图像

Nat*_*pos 17 javascript file-io jquery force-download

我想知道是否有任何方法可以使用Javascript/jQuery下载(打开下载对话框)图像,以便浏览器不会只显示它.

Sal*_*n A 35

您需要为此使用服务器端脚本.在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
Run Code Online (Sandbox Code Playgroud)

测试要求:

HEAD /test/Water%20lilies.jpg HTTP/1.1
Host: localhost
Run Code Online (Sandbox Code Playgroud)

测试响应:

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
Run Code Online (Sandbox Code Playgroud)

HTML5解决方案

您可以在锚点上使用HTML5 download属性:

<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>
Run Code Online (Sandbox Code Playgroud)

  • HTML 5解决方案简直令人惊叹 (7认同)
  • 下载属性不受广泛支持.除非您计划为不受支持的浏览器实施回退,否则您可能不应该使用它.http://caniuse.com/download (5认同)
  • 截至2016年safari仍然不支持它.我不知道IE,但谁关心IE ... (2认同)

Sha*_*ard 14

我已经提出了纯JavaScript方式来强制下载图像,但有以下限制:

  1. 在IE9之前使用HTML5在IE浏览器中根本不工作.
  2. 在IE(甚至9)中限于非常小的图像,由于URL长度限制.
  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;
}
Run Code Online (Sandbox Code Playgroud)

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

使用示例也如下.

HTML:

<image id="myimage" src="Penguins.jpg" />
<button type="btnDownload" rel="myimage">Download</button>
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

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

由于相同的来源政策不能在jsFiddle上发布实例 - 他们使用"沙盒"域来执行脚本.


Tri*_*cey 5

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

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

  • 检查这个 http://caniuse.com/#feat=download,请注意,虽然据说它应该与 FF 39 一起使用,但我用图像测试了它并显示在浏览器中 (3认同)
  • 我用 Firefix Developer Edition v43、Firefox v39、Microsost Edge、Internet Explorer v11 测试,页面中显示图像,没有出现下载对话框 (2认同)
  • 所有下载问题的简单解决方案!程序员恨他! (2认同)