JSZip 使用详解
JSZip 是一个用于创建、读取和编辑 ZIP 文件的 JavaScript 库,完全在浏览器中运行,也支持 Node.js 环境。
安装
浏览器环境
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
Node.js 环境
npm install jszip
# 或
yarn add jszip
基本使用
1. 创建一个 ZIP 文件
const JSZip = require("jszip"); // Node.js 中需要
const zip = new JSZip();
// 添加文本文件
zip.file("hello.txt", "Hello World\n");
// 添加文件夹
const img = zip.folder("images");
// 在文件夹中添加文件
img.file("smile.gif", base64Data, {base64: true});
// 生成 ZIP 文件
zip.generateAsync({type:"blob"})
.then(function(content) {
// 下载 ZIP 文件
saveAs(content, "example.zip");
});
2. 读取 ZIP 文件
// 假设 file 是用户通过 input[type=file] 选择的 ZIP 文件
function readZip(file) {
JSZip.loadAsync(file)
.then(function(zip) {
// 获取所有文件和文件夹
Object.keys(zip.files).forEach(function(filename) {
const file = zip.files[filename];
if (!file.dir) {
// 如果是文件而不是文件夹
file.async("text").then(function(fileData) {
console.log(filename, fileData);
});
}
});
})
.catch(function(err) {
console.error(err);
});
}
核心 API
创建和添加内容
new JSZip()
- 创建一个新的 JSZip 实例.file(name, data[, options])
- 添加一个文件.folder(name)
- 创建一个文件夹.remove(name)
- 删除文件或文件夹
读取内容
.file(name)
- 获取文件.files
- 获取所有文件.forEach(callback)
- 遍历所有文件.filter(callback)
- 过滤文件
生成 ZIP
.generateAsync(options)
- 异步生成 ZIP 文件.generateNodeStream(options)
- Node.js 流式生成
进阶功能
1. 添加二进制数据
// 添加 ArrayBuffer
fetch('image.png')
.then(res => res.arrayBuffer())
.then(data => {
zip.file("image.png", data);
});
// 添加 Blob
zip.file("image.jpg", blobData);
2. 设置文件属性
zip.file("readme.txt", "This is a readme", {
date: new Date(2020, 0, 1), // 设置日期
unixPermissions: "644", // UNIX 权限
dosPermissions: null, // DOS 权限
comment: "First comment", // 注释
createFolders: true // 自动创建文件夹
});
3. 处理大型文件
// 使用流式处理大型文件 (Node.js)
const fs = require('fs');
const stream = fs.createReadStream('large-file.bin');
zip.file("large-file.bin", stream);
// 生成时使用流式输出
const zipStream = zip.generateNodeStream({type:'nodebuffer', streamFiles:true});
zipStream.pipe(fs.createWriteStream('output.zip'))
.on('finish', function () {
console.log("output.zip written.");
});
4. 密码保护 (需要 JSZip 第三方插件)
// 注意:这不是 JSZip 核心功能,需要额外插件
const password = "secret";
zip.generateAsync({
type: "blob",
encryption: "AES-256", // 加密类型
password: password // 密码
}).then(function(content) {
saveAs(content, "protected.zip");
});
实际应用示例
1. 打包多个文件下载
async function downloadFilesAsZip(files) {
const zip = new JSZip();
const promises = [];
files.forEach(file => {
promises.push(
fetch(file.url)
.then(res => res.blob())
.then(blob => {
zip.file(file.name, blob);
})
);
});
await Promise.all(promises);
const content = await zip.generateAsync({type: "blob"});
saveAs(content, "download.zip");
}
2. 在浏览器中预览 ZIP 内容
document.getElementById('zip-input').addEventListener('change', function(e) {
const file = e.target.files[0];
const zip = new JSZip();
zip.loadAsync(file)
.then(function() {
const preview = document.getElementById('preview');
preview.innerHTML = '';
zip.forEach(function(relativePath, file) {
const div = document.createElement('div');
div.textContent = relativePath;
preview.appendChild(div);
});
});
});
3. 从 ZIP 中提取特定文件
async function extractFileFromZip(zipFile, targetFileName) {
const zip = await JSZip.loadAsync(zipFile);
const file = zip.file(targetFileName);
if (!file) {
throw new Error('File not found in zip');
}
return file.async('text'); // 或 'arraybuffer', 'blob' 等
}
注意事项
- 浏览器兼容性:JSZip 支持大多数现代浏览器,包括 IE10+
- 性能考虑:处理大型 ZIP 文件可能会占用大量内存
- Node.js 特定功能:如流式处理仅在 Node.js 中可用
- ZIP 规范支持:JSZip 支持大多数常见的 ZIP 功能,但不支持所有 ZIP 特性
JSZip 是一个功能强大且灵活的库,非常适合在 Web 应用中处理 ZIP 文件,无论是创建、读取还是修改 ZIP 存档。