js图片下载之前端部分

  目录

js控制图片下载

js图片下载之前端部分

这两天有一个小需求,就是点击页面中的下载按钮,下载指定的图片。经过一番的小研究,发现想实现这个功能,基本上都用到a标签的download属性,也就a标签的href指向图片地址,加上download属性后,点a标签就可以下载图片了。但是,有个问题,这需要在同域名下才好用,跨域貌似都不行,所以,在跨域的情况下就得另想办法。我总结了两种方法,一一道来。

方法一

利用canvas,就是有一个图片地址,利用canvas把图片画出来,之后再通过canvas的toDataURL方法,将图片转为base64的数据,再把这个数据赋值给a标签的href属性,就可以了。这里注意一点,canvas调取toDataURL方法时,如果是跨域图片需要后台允许跨域,还需要在img标签的”crossOrigin”属性设置为’Anonymous’才管用,最后贴出具体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function downloadImg(url){
// 通过构造函数来创建的 img 实例,在赋予 src 值后就会立刻下载图片,相比 createElement() 创建 <img> 省去了 append(),也就避免了文档冗余和污染
var Img = new Image(),
dataURL='';
Img.setAttribute("crossOrigin",'Anonymous'); // 这里允许了跨域图片
Img.src=url;
Img.onload=function(){ // 要先确保图片完整获取到,这是个异步事件
var canvas = document.createElement("canvas"), // 创建canvas元素
width=Img.width, // 确保canvas的尺寸和图片一样
height=Img.height;
canvas.width=width;
canvas.height=height;
canvas.getContext("2d").drawImage(Img,0,0,width,height); // 将图片绘制到canvas中
dataURL=canvas.toDataURL('image/jpeg'); // 转换图片为dataURL
var a = document.createElement('a'),
body = document.body;
a.download = 'img.jpg';
a.href = dataURL;
body.append(a);
a.click();
body.removeChild(a);
};
}

方法二

第二种方法就需要后端配合了,前端使用ajax请求到图片的二进制数据,之后利用了FileReader这个API,具体看代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 function downloadImg(url) {
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true); // 请求方式
xhr.responseType = "blob"; // 返回类型blob
xhr.onload = function () {
// 请求完成
if (this.status === 200) {
// 返回200
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob); // 转换为base64,可以直接放入a标签的href
reader.onload = function (e) {
// 转换完成,创建一个a标签用于下载
var a = document.createElement('a'),
body = document.body;
a.download = 'img.jpg';
a.href = e.target.result;
body.append(a);
a.click();
body.removeChild(a);
}
}
};
// 发送ajax请求
xhr.send()
}

这个方法需要后端发送图片的二进制数据,我也写了nodejs的发送方法,见《js图片下载之后端部分》

方法三

这种方式兼容性比较好,方法二在ie(11)下是不兼容的,最好的兼容方法莫过于后端写一个返回图片流的get方式的接口,这样直接window.open或者a标签链接再或者form都可以直接下载,如果后端是post方式,那就只能是form来解决了,见代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
function downloadFile() {
var form = document.createElement('form'); //创建form标签
form.setAttribute("style","display:none");
form.setAttribute("method","post");//设置请求方式
form.setAttribute("action", hostUrl + '/imgpath'); //action属性设置请求路径
document.body.appendChild(form); //页面添加form标签
var input1 = document.createElement("input") //创建input标签
input1.setAttribute("name", "id") //参数名
input1.setAttribute("value", 1) //参数值
form.appendChild(input1);
form.submit();//表单提交即可下载!
document.body.removeChild(form); //页面删除form标签
}