油猴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将任意内容嵌入到网页中。