强制使用Javascript下载图像

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

你需要使用服务器端脚本。 在stackoverflow上search 。

或者,您的服务器可能允许您通过configurationdynamic更改标题。

Apache解决scheme与mod_headers

将可下载的图像放在一个目录中。 在这个目录下,用下面的内容创build一个.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 

testing要求:

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

testing回应:

 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解决scheme

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

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

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

  1. 在IE9之前使用HTML5在IE浏览器中根本不工作。
  2. 在IE(甚至9)限于非常小的图像,由于URL长度限制。
  3. 图片名称(当保存到机器)不能在代码中确定,在Chrome中它将只是“下载”而不扩展,在Firefox中它将看起来像带有“.part”扩展名的乱码string – 无论哪种方式,用户将不得不重新命名该文件使其可用。
  4. 只能下载相同域中的图像 – 相同的来源策略。

上面的限制(特别是第三个)或多或less使这个无用的,但仍然是“核心”的想法有效的,希望在未来的某个时候,将有可能确定文件名,然后将变得更有用。

这里是代码:

 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 MIMEtypes强制下载并更改浏览器位置。

使用示例如下。

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); } 

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

由于相同的来源政策不能在jsFiddle发布现场示例 – 他们正在使用“沙箱”域来执行脚本。

这是一个简单的解决scheme,它使用HTML5的“下载”属性:

 document.getElementById('download').click(); 
 <a id="download" href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download hidden></a> 

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

我猜你的意思是这样的:

在浏览器中转到url,URL是: http : //example.com/image.png

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

我相当肯定,你不能强制这与JavaScript和将需要一个服务器端语言来控制头。 即使在这一点上,你不能强迫浏览器下载它,每个useragent会对你发送的任何头文件作出不同的反应。

编辑:我似乎记得头是Content-Disposition: attachment;

Interesting Posts