油猴Tampermonkey脚本-纯js实现图片打包下载
在前一篇文章的最后(强大的油猴Tampermonkey脚本开发环境搭建),我提到了我练手的时候开发了一个Instagram图片批量下载脚本,但是当时这个脚本我说是有缺陷的,批量图片下载貌似最多只能12个任务同时下载,也就是最多只能下载12张图片。
我就在找寻,是否存在一种方法,可以将这些图片仅通过前端就可以进行打包成为.zip
文件,然后下载一个压缩包。
后面我就找到了一个jszip
库,使用它就可以实现在前端打包文件进行下载。
来看看最终效果:
1. 正文
- jszip:https://github.com/Stuk/jszip。
- FileSaver.js:https://github.com/eligrey/FileSaver.js
jszip
这个库使用起来是非常方便的,也非常简单。
import JSZip from "jszip";
import { saveAs } from 'file-saver';
const zip = new JSZip();
// 创建一个名为images的文件夹
const img = zip.folder("images");
// 3个参数分别是文件名、图片的base64编码、和base64验证
img.file("smile.gif", imgData, {base64: true});
zip.generateAsync({type:"blob"}).then(function(content) {
// 使用FileSaver.js下载到本地
saveAs(content, "example.zip");
});
就是这么简单,一般来说网页上面的图片都是url形式的,那么如何将url转为base64呢?其实直接使用canvas就可以转换,代码如下所示。
/**
* 转一张图片编码
* @param {string} imgUrl 图片url
* @return {Promise<string>}
*/
function getBase64(imgUrl) {
return new Promise((resolve) => {
const image = new Image();
image.crossOrigin = ""; // 解决跨域问题
image.src = imgUrl;
image.onload = function () {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
// 得到图片的base64编码数据
resolve(canvas.toDataURL("image/png", 1).split(",")[1]);
};
});
}
因为该函数为异步函数,所以需要使用Promise.all()
或者配合async、await
进行使用。
2. 脚本编写遇到的坑
2.1 async、await不能用
因为getBase64()
函数为异步函数,所以要等待全部的图片都转为了base64,然后再添加到jszip
进行压缩,如果不处理该异步问题,最后压缩出来的内容为空,没有图片。
最开始async、await
无法使用,导致我使用了Promise.all()
,最后发现使用Promise.all()
的话制作进度条时不好处理,找了很多文章发现异常的麻烦,于是转头开始调查为什么async、await
无法使用,最后发现需要安装下面的包:
npm i regenerator-runtime -D
该包貌似是专门处理async、await
在ES5中的兼容性问题。
2.2 图片打包时报错
因为canvas转换出来会加上data:image/png;base64,
这一段,所以会报Error: Invalid base64 input, it looks like a data url.
这个错误,所以使用.split(",")[1]
将前面的那段去掉就好了。
3. 最后
最后不得不惊叹油猴脚本的厉害之处,可以通过JavaScript将任意内容嵌入到网页中。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!