使用JSZip实现在浏览器中操作文件与文件夹

1. 引言

浏览器中如何创建文件夹、写入文件呢?

答曰:可以借助JSZip这个库来实现在浏览器内存中创建文件与文件夹,最后只需下载这个.zip文件,就是最终得结果

类似的使用场景如下:

  • 在线下载很多图片,希望这些图片能分类保存到各个文件夹并最终下载成一个zip文件
  • 在线下载很多文档,希望这些文档能分类保存到各个文件夹并最终下载成一个zip文件

本质上都是希望浏览器能创建文件夹和创建文件,最终保存成一个文件来提供下载

JSZip的GitHub站点:Stuk/jszip: Create, read and edit .zip files with Javascript (github.com)

一个可用的中文站点:JSZip参考手册 (asprain.cn)

下面主要记录一下基础使用,详细的API请参考上述文档

2. 使用

2.1 安装

使用NPM:

shell 复制代码
npm install jszip

使用在线CDN:

html 复制代码
<script src="https://cdn.bootcdn.net/ajax/libs/jszip/3.10.1/jszip.js"></script>
  • 为了可以代码可以快速复现,笔者这里使用CDN的方式引入

2.2 创建zip实例

一个JSZip实例是读写.zip文件的基础

javascript 复制代码
const zip = new JSZip();

2.3 读取zip文件

读取官方的示例文件text.zip

javascript 复制代码
const zip = new JSZip();

fetch("https://stuk.github.io/jszip/test/ref/text.zip")       // 1) fetch the url
    .then(function (response) {                       // 2) filter on 200 OK
        if (response.status === 200 || response.status === 0) {
            return Promise.resolve(response.blob());
        } else {
            return Promise.reject(new Error(response.statusText));
        }
    })
    .then(data => zip.loadAsync(data))                            // 3) 加载数据
    .then(function (zip) {
        zip.forEach(function (relativePath, file) {  	// 4) 遍历压缩包内的文件
           console.log(`path: ${relativePath}, file: ${file.name}`)
           // 输出:path: Hello.txt, file: Hello.txt
        });
})

因为Hello.txt是个文本文件,可以直接使用string的方式读取内部的数据

javascript 复制代码
const zip = new JSZip();

fetch("https://stuk.github.io/jszip/test/ref/text.zip")       // 1) fetch the url
    .then(function (response) {                       // 2) filter on 200 OK
        if (response.status === 200 || response.status === 0) {
            return Promise.resolve(response.blob());
        } else {
            return Promise.reject(new Error(response.statusText));
        }
    })
    .then(data => zip.loadAsync(data))                            // 3) chain with the zip promise
    .then(function (zip) {
        return zip.file("Hello.txt").async("string"); // 4) 读取Hello.txt文件
    })
    .then(function success(text) {
        console.log(text); // 输出:Hello World
    }, function error(e) {
        console.error(e);
    });

2.4 创建zip文件

写入文件与数据

javascript 复制代码
zip.file("file.txt", "content");
new Promise((resolve, reject) => {
    resolve(zip.file("file.txt").async("string"))
}).then(data => {
    console.log(data); // 输出:content
})

写入指定文件夹下的指定文件

javascript 复制代码
zip.file("text/file.txt", "content");
zip.forEach(function (relativePath, file) {
    console.log(`path: ${relativePath}, file: ${file.name}`)
    // 输出:path: text/file.txt, file: text/file.txt
});

最后的目录结构可以参考下图

2.5 下载zip文件

这里将上面的file.txt下载为zip,使用a链接的方式

javascript 复制代码
zip.generateAsync({ type: "blob" }).then(function (content) {
    document.body.appendChild(document.createElement("a"));
    document.querySelector("a").href = URL.createObjectURL(content);
    document.querySelector("a").download = "test.zip";
    document.querySelector("a").click();
});

完整的代码如下:

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jszip/3.10.1/jszip.js"></script>
</head>

<body>

    <script>
        const zip = new JSZip();

        // fetch("https://stuk.github.io/jszip/test/ref/text.zip")       // 1) fetch the url
        //     .then(function (response) {                       // 2) filter on 200 OK
        //         if (response.status === 200 || response.status === 0) {
        //             return Promise.resolve(response.blob());
        //         } else {
        //             return Promise.reject(new Error(response.statusText));
        //         }
        //     })
        //     .then(data => zip.loadAsync(data))                            // 3) chain with the zip promise
        //     .then(function (zip) {
        //         return zip.file("Hello.txt").async("string"); // 4) chain with the text content
        //     })
        //     .then(function success(text) {
        //         console.log(text);
        //     }, function error(e) {
        //         console.error(e);
        //     });
        zip.file("text/file.txt", "content");
        zip.forEach(function (relativePath, file) { 
           console.log(`path: ${relativePath}, file: ${file.name}`)
        });

        zip.generateAsync({ type: "blob" }).then(function (content) {
            document.body.appendChild(document.createElement("a"));
            document.querySelector("a").href = URL.createObjectURL(content);
            document.querySelector("a").download = "test.zip";
            document.querySelector("a").click();
        });
    </script>

</body>

</html>

3. 参考资料

1\] [How to use JSZip (stuk.github.io)](https://stuk.github.io/jszip/documentation/examples.html) \[2\] [JSZip参考手册 (asprain.cn)](http://docs.asprain.cn/jszip/jszip.html#)

相关推荐
Wect1 小时前
浏览器缓存机制
前端·面试·浏览器
FliPPeDround4 天前
浏览器扩展 E2E 测试的救星:vitest-environment-web-ext 让你告别繁琐配置
e2e·浏览器·测试
SuperEugene4 天前
浏览器存储:localStorage / sessionStorage / cookie 应该怎么用
前端·javascript·面试·浏览器
宁雨桥4 天前
浏览器渲染原理
前端·浏览器·原理
YZ0996 天前
2026年如何批量保存小红书作者主页的视频、图片和文案?
经验分享·浏览器·插件
程序员ys6 天前
网页白屏的原理与优化
前端·性能优化·浏览器
Wect8 天前
从输入URL到页面显示的完整技术流程
前端·面试·浏览器
NEXT068 天前
从输入 URL 到页面展示的完整链路解析
网络协议·面试·浏览器
CappuccinoRose11 天前
CSS 语法学习文档(十五)
前端·学习·重构·渲染·浏览器
REDcker12 天前
Media Source Extensions (MSE) 详解
前端·网络·chrome·浏览器·web·js