news 2026/1/19 8:04:25

JS文件批量下载并打包成ZIP的功能

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JS文件批量下载并打包成ZIP的功能

方法一:使用JSZip和FileSaver(推荐)

1. 安装依赖

npm install jszip file-saver # 或使用CDN

2. HTML结构

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>JS文件批量下载</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script> <style> .container { max-width: 800px; margin: 0 auto; padding: 20px; } .file-list { margin: 20px 0; padding: 10px; border: 1px solid #ddd; max-height: 300px; overflow-y: auto; } .file-item { display: flex; justify-content: space-between; align-items: center; padding: 8px; border-bottom: 1px solid #eee; } .progress-bar { width: 100%; height: 20px; background-color: #f0f0f0; border-radius: 10px; margin: 10px 0; overflow: hidden; } .progress { height: 100%; background-color: #4CAF50; width: 0%; transition: width 0.3s; } button { background-color: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; } button:hover { background-color: #45a049; } button:disabled { background-color: #cccccc; cursor: not-allowed; } </style> </head> <body> <div class="container"> <h1>JS文件批量下载器</h1> <!-- 文件输入区域 --> <div> <h3>选择JS文件</h3> <input type="file" id="fileInput" multiple accept=".js" /> <button onclick="addFiles()">添加文件</button> </div> <!-- URL输入区域 --> <div style="margin-top: 20px;"> <h3>或输入JS文件URL</h3> <div style="display: flex; gap: 10px;"> <input type="text" id="urlInput" placeholder="输入JS文件URL" style="flex: 1; padding: 8px;" /> <button onclick="addURL()">添加URL</button> </div> </div> <!-- 文件列表 --> <div class="file-list" id="fileList"> <p>已选择文件:<span id="fileCount">0</span>个</p> </div> <!-- 进度条 --> <div id="progressContainer" style="display: none;"> <div class="progress-bar"> <div class="progress" id="progress"></div> </div> <p id="progressText">准备中...</p> </div> <!-- 下载按钮 --> <div style="margin-top: 20px;"> <button onclick="downloadAllAsZip()" id="downloadBtn" disabled>打包下载ZIP</button> <button onclick="clearFiles()" style="background-color: #f44336; margin-left: 10px;">清空列表</button> </div> </div> <script src="main.js"></script> </body> </html>

3. JavaScript主逻辑 (main.js)

let files = []; let fileCounter = 1; // 添加本地文件 function addFiles() { const fileInput = document.getElementById('fileInput'); const selectedFiles = Array.from(fileInput.files); selectedFiles.forEach(file => { if (file.type === 'application/javascript' || file.name.endsWith('.js')) { files.push({ id: fileCounter++, name: file.name, content: file, type: 'local' }); } }); updateFileList(); fileInput.value = ''; } // 添加URL文件 async function addURL() { const urlInput = document.getElementById('urlInput'); const url = urlInput.value.trim(); if (!url) { alert('请输入有效的URL'); return; } if (!url.endsWith('.js')) { alert('请输入JS文件的URL'); return; } // 从URL提取文件名 const fileName = url.split('/').pop() || `file_${fileCounter}.js`; files.push({ id: fileCounter++, name: fileName, url: url, type: 'url' }); updateFileList(); urlInput.value = ''; } // 更新文件列表显示 function updateFileList() { const fileList = document.getElementById('fileList'); const fileCount = document.getElementById('fileCount'); const downloadBtn = document.getElementById('downloadBtn'); fileList.innerHTML = '<p>已选择文件:<span id="fileCount">' + files.length + '</span>个</p>'; files.forEach(file => { const div = document.createElement('div'); div.className = 'file-item'; div.innerHTML = ` <span>${file.name}</span> <button onclick="removeFile(${file.id})" style="background-color: #ff4444; padding: 4px 8px; font-size: 12px;"> 删除 </button> `; fileList.appendChild(div); }); fileCount.textContent = files.length; downloadBtn.disabled = files.length === 0; } // 移除文件 function removeFile(id) { files = files.filter(file => file.id !== id); updateFileList(); } // 清空所有文件 function clearFiles() { if (confirm('确定要清空所有文件吗?')) { files = []; updateFileList(); } } // 主下载函数 async function downloadAllAsZip() { if (files.length === 0) { alert('请先添加文件'); return; } const progressContainer = document.getElementById('progressContainer'); const progressBar = document.getElementById('progress'); const progressText = document.getElementById('progressText'); const downloadBtn = document.getElementById('downloadBtn'); // 显示进度条 progressContainer.style.display = 'block'; downloadBtn.disabled = true; try { const zip = new JSZip(); let processed = 0; // 处理每个文件 for (const file of files) { progressText.textContent = `正在处理: ${file.name} (${processed + 1}/${files.length})`; if (file.type === 'local') { // 本地文件 const content = await readFileAsText(file.content); zip.file(file.name, content); } else if (file.type === 'url') { // 远程文件 try { const response = await fetch(file.url); if (!response.ok) { throw new Error(`下载失败: ${response.status} ${response.statusText}`); } const content = await response.text(); zip.file(file.name, content); } catch (error) { console.error(`下载 ${file.url} 失败:`, error); zip.file(file.name, `// 下载失败: ${error.message}\n// 原始URL: ${file.url}`); } } processed++; const progressPercent = (processed / files.length) * 100; progressBar.style.width = `${progressPercent}%`; } // 生成ZIP文件 progressText.textContent = '正在生成ZIP文件...'; const zipBlob = await zip.generateAsync({ type: 'blob', compression: 'DEFLATE', compressionOptions: { level: 6 } }, (metadata) => { if (metadata.percent) { progressBar.style.width = `${metadata.percent}%`; progressText.textContent = `正在压缩: ${Math.round(metadata.percent)}%`; } }); // 下载ZIP文件 progressText.textContent = '正在下载...'; saveAs(zipBlob, `js-files-${new Date().toISOString().slice(0, 10)}.zip`); progressText.textContent = '下载完成!'; setTimeout(() => { progressContainer.style.display = 'none'; progressBar.style.width = '0%'; downloadBtn.disabled = false; }, 2000); } catch (error) { console.error('打包失败:', error); alert(`打包失败: ${error.message}`); progressContainer.style.display = 'none'; downloadBtn.disabled = false; } } // 读取本地文件为文本 function readFileAsText(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => resolve(e.target.result); reader.onerror = (e) => reject(new Error('文件读取失败')); reader.readAsText(file); }); }

方法二:使用StreamSaver处理大文件

如果需要处理非常大的文件,可以使用StreamSaver:

<!-- 在head中添加 --> <script src="https://cdn.jsdelivr.net/npm/web-streams-polyfill@2.0.2/dist/ponyfill.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/streamsaver@2.0.3/StreamSaver.min.js"></script>
// 替换之前的下载函数 async function downloadLargeFilesAsZip() { if (files.length === 0) return; // 创建可写流 const fileStream = streamSaver.createWriteStream('js-files.zip'); const writer = fileStream.getWriter(); // 使用JSZip生成流 const zip = new JSZip(); // 添加文件到zip... // ... 处理文件逻辑 // 生成并写入流 zip.generateInternalStream({ type: 'blob', streamFiles: true }).on('data', (chunk) => { writer.write(chunk); }).on('end', () => { writer.close(); }).resume(); }

方法三:使用Node.js后端打包

如果需要处理大量文件或跨域问题,可以使用Node.js后端:

// server.js const express = require('express'); const archiver = require('archiver'); const axios = require('axios'); const app = express(); app.post('/download-js', async (req, res) => { const { urls } = req.body; res.setHeader('Content-Type', 'application/zip'); res.setHeader('Content-Disposition', 'attachment; filename=js-files.zip'); const archive = archiver('zip', { zlib: { level: 9 } }); archive.pipe(res); for (const url of urls) { try { const response = await axios.get(url, { responseType: 'stream' }); const filename = url.split('/').pop(); archive.append(response.data, { name: filename }); } catch (error) { console.error(`Failed to fetch ${url}:`, error); } } archive.finalize(); }); app.listen(3000, () => { console.log('Server running on port 3000'); });

使用说明

  1. 本地文件:选择本地的JS文件

  2. 远程文件:输入JS文件的URL地址

  3. 打包下载:点击"打包下载ZIP"按钮

  4. 清空列表:点击"清空列表"按钮移除所有文件

注意事项

  1. 跨域问题:如果JS文件来自不同源且没有CORS头,可能无法下载

  2. 文件大小:前端处理大量大文件时可能内存不足

  3. 浏览器兼容性:现代浏览器支持良好,IE需要polyfill

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/19 0:06:27

飞书文档批量导出终极指南:一键解决文档迁移难题

飞书文档批量导出终极指南&#xff1a;一键解决文档迁移难题 【免费下载链接】feishu-doc-export 项目地址: https://gitcode.com/gh_mirrors/fe/feishu-doc-export 你是否曾经为文档迁移而头疼不已&#xff1f;当公司决定更换办公平台&#xff0c;或是需要将飞书知识库…

作者头像 李华
网站建设 2026/1/18 9:40:47

Source Han Serif思源宋体:免费开源中文字体专业应用指南

Source Han Serif思源宋体&#xff1a;免费开源中文字体专业应用指南 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 还在为字体版权问题而烦恼&#xff1f;Source Han Serif思源宋体为…

作者头像 李华
网站建设 2026/1/18 3:43:14

DOM Element:深入理解与操作

DOM Element:深入理解与操作 引言 在Web开发领域,DOM(文档对象模型)是一个至关重要的概念。DOM允许开发者与网页内容进行交互,如HTML和XML文档。DOM Element是DOM模型中的核心组成部分,它代表了HTML或XML文档中的每一个元素。本文将深入探讨DOM Element的概念、属性、方…

作者头像 李华
网站建设 2026/1/18 1:31:06

Turnitin系统查英文AI率多少为正常?报告显示星号*%怎么办?

很多学校和杂志社都在说需要检测论文AI率&#xff0c;但是论文AI率多少才算正常呢&#xff1f; Turnitin系统AI检测系统&#xff1a;https://students-turnai.similarity-check.com/ 今天这篇内容就给大家分享一下。 很多同学使用Turnitin系统检测了英文论文AI率之后&#x…

作者头像 李华
网站建设 2026/1/18 10:22:54

暖通净化空调恒温恒湿项目:PLC 与触摸屏上位机程序探秘

暖通净化空调恒温恒湿项目包括PLC程序和触摸屏上位机程序。 标准化很好的内部用的函数都封装成了标准块一套很好的学习资料。在暖通净化空调恒温恒湿项目里&#xff0c;PLC 程序和触摸屏上位机程序就像项目运转的左膀右臂&#xff0c;承担着关键任务。先聊聊 PLC 程序&#xff…

作者头像 李华