概要
实现一个前端在浏览器页面中预览zip压缩包里面的目录功能
实现思路
创建一个文件输入框,用户可以选择zip文件。当用户选择文件后,代码会读取文件内容并使用jszip库解析zip文件。然后,遍历zip文件中的所有文件,将它们添加到一个名为fileTree的div元素中,以显示文件层级结构
实现细节
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>预览zip文件</title>
</head>
<body>
<input type="file" id="zipFile" accept=".zip" />
<div id="fileTree"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script>
const zipFileInput = document.getElementById('zipFile');
const fileTree = document.getElementById('fileTree');
zipFileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
const data = e.target.result;
const zip = new JSZip();
zip.loadAsync(data).then((zip) => {
const fileNames = Object.keys(zip.files);
fileTree.innerHTML = '';
fileNames.forEach((fileName) => {
const folderPath = fileName.split('/').slice(0, -1).join('/');
const filePath = fileName.split('/').slice(-1)[0];
const parentFolder = fileTree.querySelector(`[data-folder="${folderPath}"]`);
if (!parentFolder) {
const parentFolderElem = document.createElement('div');
parentFolderElem.setAttribute('data-folder', folderPath);
parentFolderElem.textContent = folderPath;
fileTree.appendChild(parentFolderElem);
}
const fileElem = document.createElement('a');
fileElem.href = URL.createObjectURL(zip.files[fileName].blob());
fileElem.download = filePath;
fileElem.textContent = filePath;
parentFolder.appendChild(fileElem);
});
});
};
reader.readAsArrayBuffer(file);
});
</script>
</body>
</html>
但是大部分时候,zip文件不是本地文件,而是通过网络请求下载的,如何处理浏览器下载zip文件,并读取文件内容呢?前端下载zip文件的时候,直接将它转为一个file对象解析,请看下面的代码示例
// 获取 zip 文件的 URL
const zipUrl = 'https://example.com/path/to/your/zipfile.zip';
// 创建一个新的 Promise
const downloadPromise = new Promise((resolve, reject) => {
// 使用 fetch API 下载 zip 文件
fetch(zipUrl)
.then(response => response.arrayBuffer())
.then(data => {
// 将二进制数据转换为 Blob 对象
const blob = new Blob([data], { type: 'application/zip' });
// 创建一个用于存储 zip 数据的数组
const zipData = [];
// 使用 FileReader API 读取 zip 文件内容
const reader = new FileReader();
reader.onloadend = () => {
// 解析 zip 文件内容
const zip = new JSZip();
zip.loadAsync(reader.result).then(() => {
// 遍历 zip 文件中的所有文件和文件夹
zip.forEach((relativePath, zipEntry) => {
// 将文件或文件夹添加到 zipData 数组中
zipData.push({ relativePath, zipEntry });
});
// 解析完成后,调用 resolve 函数
resolve(zipData);
});
};
reader.readAsArrayBuffer(blob);
})
.catch(error => {
// 如果发生错误,调用 reject 函数
reject(error);
});
});
// 使用 Promise 处理下载结果
downloadPromise.then(zipData => {
// 在这里处理 zip 文件的文件层级信息
console.log(zipData);
}).catch(error => {
// 在这里处理错误信息
console.error(error);
});