使用Javascript强制下载图像

时间:2011-07-22 22:57:55

标签: javascript jquery file-io force-download

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

5 个答案:

答案 0 :(得分:35)

您需要为此使用服务器端脚本。 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>

答案 1 :(得分:14)

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

  1. 使用HTML5,以便在IE9之前的IE浏览器中完全不起作用。
  2. 由于URL长度限制,在IE(甚至9)中仅限于非常小的图像。
  3. 图片名称(保存到机器时)无法在代码中确定,在Chrome中它只是“下载”而没有扩展名,在Firefox中它将看起来像带有“.part”扩展名的乱码字符串 - 无论哪种方式,用户都必须重命名该文件才能使其可用。
  4. 只能下载同一域中的图像 - 同源策略。
  5. 上述限制(特别是第三种)或多或少会使这无用,但仍然,“核心”想法 正在工作,并希望将来在某个时候可以确定文件名然后它会变得更有用。

    以下是代码:

    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上发布实例 - 他们正在使用“沙盒”域来执行脚本。

答案 2 :(得分:4)

这是一个使用HTML5&#39;下载&#39;的简单解决方案。属性:

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

答案 3 :(得分:0)

我猜你的意思是这样的:

在浏览器中转到网址,网址为:http://example.com/image.png

而不是显示,浏览器会提示您保存图像?

我很确定你不能用javascript强制这个,并且需要一个服务器端语言来控制头文件。即使在那时你也不能强迫浏览器下载它,每个useragent会对你发送的任何标题作出不同的反应。

编辑:我似乎记得标题为Content-Disposition: attachment;

答案 4 :(得分:0)

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