HTML5 的 File API 本身不支持前端解压 ZIP,但配合 JSZip 库可解析 ZIP 元数据(文件名、大小、目录结构);需用 file.arrayBuffer() 获取二进制数据传入 JSZip.loadAsync(),再遍历 zip.files 提取信息,并校验路径防 XSS,禁止使用 readAsDataURL 或 readAsText 解析 ZIP。

用 <input type="file"> 选中压缩包但不上传到服务器
浏览器原生不支持在前端解压 ZIP,但可以读取压缩包的元数据(如文件名、大小、目录结构),前提是用 JavaScript 解析 ZIP 格式。关键不是“上传”,而是“读取本地文件内容”。<input type="file" accept=".zip,.rar,.7z"> 只负责选中文件,后续全靠 JS 处理。
注意:accept 属性仅过滤文件选择器界面,不能阻止用户手动拖入其他类型;真正校验必须在 change 事件里检查 file.type 或后缀名:
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file || !/\.zip$/i.test(file.name)) {
alert('请选 ZIP 文件');
return;
}
// 后续解析逻辑
});用 JSZip 在前端解析 ZIP 并列出文件
JSZip 是最成熟、兼容性好的纯前端 ZIP 解析库(不依赖后端)。它能读取 ZIP 的中央目录,提取所有文件路径、大小、是否为目录等信息,无需解压到磁盘。
- 通过
file.arrayBuffer()获取二进制数据,传给JSZip.loadAsync() -
zip.file()返回匹配路径的文件对象,zip.folder()返回子目录 - 遍历
zip.files对象的键(即文件路径),用file.name和file.dir判断类型 - 注意:
JSZip不支持 RAR/7z,那些需用对应库(如libarchive.js),但体积大、兼容差
简单示例:
立即学习“前端免费学习笔记(深入)”;
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
const zip = await JSZip.loadAsync(file.arrayBuffer());
const entries = [];
zip.forEach((relativePath, zipEntry) => {
entries.push({
name: relativePath,
size: zipEntry._data?.uncompressedSize || 0,
isDir: zipEntry.dir
});
});
// entries 就是你要渲染的文件清单列出时要注意路径处理和安全限制
ZIP 文件里的路径可能含 ../、空字符或非法 Unicode,直接渲染或拼接可能导致 XSS 或路径穿越。JSZip 默认会 normalize 路径,但仍建议过滤:
- 跳过以
/开头或含..的路径(zipEntry.name.startsWith('/') || zipEntry.name.includes('..')) - 用
encodeURIComponent处理文件名再插入 DOM,避免 HTML 注入 - 前端无法获取真实修改时间、权限等元数据 —— ZIP 中这部分常缺失或不可信
- 大 ZIP(>100MB)会导致内存暴涨甚至卡死,应加
if (file.size > 50 * 1024 * 1024)提前拦截
为什么不用 FileReader.readAsDataURL 或 readAsText?
因为 ZIP 是二进制格式,不是文本或可 base64 直接解析的结构化数据。readAsDataURL 会把整个 ZIP 编成超长字符串,浪费内存且无法直接读目录;readAsText 会乱码并中断解析。必须用 arrayBuffer + 专用 ZIP 解析器。
另外,fetch() 或 XMLHttpRequest 无法读取本地 file:// 路径,所以整个流程必须基于 input.files 和 File API,绕不开用户主动选择这一步。
真正难的不是“列出”,而是可靠地处理损坏 ZIP、密码保护 ZIP(JSZip 不支持)、超大文件流式解析(需额外分块逻辑)——这些场景基本得回退到服务端做。


















