使用 Javascript 强制下载图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6796974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Force Download an Image Using Javascript
提问by Nathan Campos
I want to know if there is any way to make a script using Javascript/jQuery to download (open a download dialog) a image so the browser won't just show it.
我想知道是否有任何方法可以使用 Javascript/jQuery 制作脚本来下载(打开下载对话框)图像,以便浏览器不只是显示它。
回答by Salman A
You need to use server-side scripting for this. Search on stackoverflow.
为此,您需要使用服务器端脚本。在 stackoverflow 上搜索。
Alternately, your server might allow you to alter headers dynamically via configuration.
或者,您的服务器可能允许您通过配置动态更改标头。
Apache solution with mod_headers
带有 mod_headers 的 Apache 解决方案
Place your downloadable images in a directory. Inside this directory, create a .htaccess
file with the following contents:
将可下载的图像放在一个目录中。在此目录中,创建一个.htaccess
包含以下内容的文件:
SetEnvIf Request_URI "([^/]+\.jpg)$" REQUESTED_IMAGE_BASENAME=
SetEnvIf Request_URI "([^/]+\.png)$" REQUESTED_IMAGE_BASENAME=
Header set Content-Disposition "attachment; filename=\"%{REQUESTED_IMAGE_BASENAME}e\"" env=REQUESTED_IMAGE_BASENAME
Test Request:
测试请求:
HEAD /test/Water%20lilies.jpg HTTP/1.1
Host: localhost
Test Response:
测试响应:
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 Solution
HTML5 解决方案
You can 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>
回答by Shadow Wizard is Ear For You
I have come up with pure JavaScript way to force download of image, with the following restrictions:
我想出了纯 JavaScript 方法来强制下载图像,但有以下限制:
- Using HTML5 so not working at all in IE browsers before IE9.
- In IE (even 9) limited to very small images, due to URL length limit.
- The image name (when saved to machine) can't be determined in the code, in Chrome it will be just "download" without extension and in Firefox it will be what looks like jibberish string with ".part" extension - either way, user will have to rename the file to make it usable.
- Can only download images in the same domain - same origin policy.
- 使用 HTML5,因此在 IE9 之前的 IE 浏览器中根本无法使用。
- 由于 URL 长度限制,在 IE(甚至 9)中仅限于非常小的图像。
- 无法在代码中确定图像名称(当保存到机器时),在 Chrome 中它只是“下载”而没有扩展名,而在 Firefox 中它看起来像是带有“.part”扩展名的乱码字符串 - 无论哪种方式,用户必须重命名文件以使其可用。
- 只能下载同一域中的图像 - 同源策略。
The above restrictions (especially the third) more or less renders this useless but still, the "core" idea isworking and hopefully at some point in the future it will be possible to determine file name then it will become much more useful.
上述限制(尤其是第三个)或多或少使这无用,但“核心”思想仍然有效,希望在将来的某个时候可以确定文件名,然后它将变得更加有用。
Here is the code:
这是代码:
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;
}
As you can see, the trick is drawing the image into canvas
object, get the raw binary data of the image then force download by using image/octet-stream
mime type and changing the browser location.
如您所见,技巧是将图像绘制到canvas
对象中,获取图像的原始二进制数据,然后通过使用image/octet-stream
mime 类型并更改浏览器位置来强制下载。
Usage sample follows as well.
用法示例如下。
HTML:
HTML:
<image id="myimage" src="Penguins.jpg" />
<button type="btnDownload" rel="myimage">Download</button>
JavaScript:
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);
}
This allows to "attach" download button to every existing image by assigning the rel
attribute of the button to the image ID - the code will do the rest and attach the actual click events.
这允许通过将rel
按钮的属性分配给图像 ID来将下载按钮“附加”到每个现有图像- 代码将完成剩下的工作并附加实际的点击事件。
Due to the same origin policy can't post live example at jsFiddle - they're using "sandbox" domain to execute the scripts.
由于同源策略无法在 jsFiddle 上发布实时示例 - 他们使用“沙箱”域来执行脚本。
回答by Triforcey
Here's a simple solution that uses the HTML5 'download' attribute:
这是一个使用 HTML5 'download' 属性的简单解决方案:
document.getElementById('download').click();
<a id="download" href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download hidden></a>
回答by buley
This is totally possible. Just encode the image as Base64 then do a window.open
with a data:image/jpg,Base64,...
-style url.
这是完全可能的。只需将图像编码为 Base64,然后window.open
使用data:image/jpg,Base64,...
-style url 即可。