前端实现文件下载
浏览器端实现点击按钮下载图片
移动端不兼容
移动端不兼容
移动端不兼容
老版本Google浏览器可以a标签直接下载,新版本会打开图片,只有图片同源才会直接下载
老版本Google浏览器可以a标签直接下载,新版本会打开图片,只有图片同源才会直接下载
老版本Google浏览器可以a标签直接下载,新版本会打开图片,只有图片同源才会直接下载
现在新版的浏览器,点击a标签进行下载图片时,往往不会按照预期实现图片的下载功能,而是会在新的窗口打开图片,代码如下:
<a href="https://static001.geekbang.org/resource/image/fa/af/face2257c62b291620a1750b4cdaf4af.jpg?x-oss-process=image/resize,m_fill,h_400,w_818" download>下载</a>
要想实现点击按钮下载图片,常见的做法是后端配置请求头来实现资源的下载,但是现在一般都前后端分离了,并且很多图片在oss上,不能直接修改通用的请求配置
当请求的图片是同源的时,可以直接通过a标签实现下载
// 网址
https://www.xxx.com
// 图片地址
https://www.xxx.com/image/1.png
当图片是cdn地址时,配置图片的请求头为当前域名也可以
// 极客时间地址
https://time.geekbang.org/
// 极客时间图片地址
https://static001.geekbang.org/resource/image/ab/9f/ab17ecf8fdb768db1362ec72c2f8ce9f.jpg
// 图片请求头配置
referer: https://time.geekbang.org/
当图片不再跨域时,可以使用的方法就比较多了:
通过blob流来实现下载:
const imgDownload = (src, name) => {
const canvas = document.createElement('canvas');
const img = document.createElement('img');
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
const context = canvas.getContext('2d');
context.drawImage(img, 0, 0, img.width, img.height);
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
canvas.toBlob(
(blob) => {
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = name || 'download'; // resource name
link.click();
},
'0.95',
);
};
img.setAttribute('crossOrigin', 'Anonymous');
img.src = src;
}
imgDownload(url, 1.png);
通过FileSaver.js实现下载
import { saveAs } from 'file-saver';
saveAs(url, 1.png)
浏览器实现批量下载在线图片到本地同一个文件夹并压缩
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
const imgBlob = (src) => {
const canvas = document.createElement('canvas');
const img = document.createElement('img');
img.setAttribute('crossOrigin', 'Anonymous');
img.src = src;
return new Promise((resolve) => {
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
const context = canvas.getContext('2d');
context.drawImage(img, 0, 0, img.width, img.height);
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
canvas.toBlob(
(blob) => {
resolve(blob);
},
'0.95',
);
};
});
};
const downloadImgs = async (urls, name) => {
const zip = new JSZip();
const imgs = zip.folder('images');
const blobs = urls.map(async (url) => {
const blob = await imgBlob(url);
return blob;
});
blobs.forEach((blob, index) => {
imgs.file(`${index}.png`, blob);
});
zip.generateAsync({ type: 'blob' }).then((content) => {
saveAs(content, `${name || 'example'.zip}`);
});
};