在 Web 应用中,除了单文件上传,很多时候我们还需要用户直接选择整个文件夹,并批量上传到远程服务器。典型场景包括:静态资源部署、文档归档、远程备份等。本文整合了 前端文件夹选择方案(webkitdirectory + File System Access API) 与 Node.js + node-ssh 后端上传,实现端到端的完整流程。
前端部分:选择文件夹并上传
前端的目标是让用户选择目录,遍历其中所有文件,并逐一上传到后端。
方案一:webkitdirectory
这是目前兼容度最好的方式,Chrome、Edge、Safari 均支持。
1<input type="file" id="folder" webkitdirectory multiple> 2<script> 3 document.getElementById('folder').addEventListener('change', async (event) => { 4 const files = event.target.files; 5 6 for (const file of files) { 7 console.log(file.webkitRelativePath, file.name); 8 9 const formData = new FormData(); 10 formData.append("file", file, file.webkitRelativePath); 11 12 await fetch("http://localhost:3000/upload", { 13 method: "POST", 14 body: formData 15 }); 16 } 17 }); 18</script> 19
优点
- ✅ 兼容度较好,支持主流浏览器。
- ✅ 能保留相对路径,方便后端还原目录结构。
缺点
- ❌ Firefox 支持度差。
- ❌ 必须通过
<input>触发,不够灵活。
方案二:File System Access API
这是现代浏览器支持的新特性,可以通过 JS 调用目录选择器。
1<script> 2async function readDir() { 3 const dirHandle = await window.showDirectoryPicker(); 4 5 for await (const entry of dirHandle.values()) { 6 if (entry.kind === "file") { 7 const file = await entry.getFile(); 8 console.log(entry.name); 9 10 const formData = new FormData(); 11 formData.append("file", file, entry.name); 12 13 await fetch("http://localhost:3000/upload", { 14 method: "POST", 15 body: formData 16 }); 17 } 18 } 19} 20</script> 21 22<button onclick="readDir()">选择文件夹并上传</button> 23
优点
- ✅ 灵活,可结合按钮、拖拽交互。
- ✅ 支持读写权限,可操作文件。
缺点
- ❌ 兼容性差,仅 Chromium 内核浏览器支持(Chrome、Edge)。
- ❌ 需要用户手动授权目录访问。
Node.js 后端:接收并通过 SSH 上传
后端主要任务:接收前端传输的文件 → 缓存到本地 → 通过 SSH 上传到远程服务器 → 删除缓存。
安装依赖
npm install express multer node-ssh
完整后端代码
1const express = require('express'); 2const multer = require('multer'); 3const { NodeSSH } = require('node-ssh'); 4const path = require('path'); 5const fs = require('fs'); 6 7const app = express(); 8const upload = multer({ dest: 'uploads/' }); 9const ssh = new NodeSSH(); 10 11// SSH 配置 12const sshConfig = { 13 host: 'your-server-ip', 14 username: 'your-username', 15 privateKey: '/path/to/private/key' // 或 password 16}; 17 18// 接收文件上传 19app.post('/upload', upload.single('file'), async (req, res) => { 20 try { 21 const localPath = req.file.path; 22 const remotePath = path.join('/remote/dir', req.file.originalname); 23 24 await ssh.connect(sshConfig); 25 await ssh.putFile(localPath, remotePath); 26 27 fs.unlinkSync(localPath); // 删除本地缓存文件 28 29 res.send('上传成功'); 30 } catch (err) { 31 console.error(err); 32 res.status(500).send('上传失败'); 33 } 34}); 35 36app.listen(3000, () => { 37 console.log('服务已启动: http://localhost:3000'); 38}); 39
工作流程
- 前端选择目录,逐个文件打包成
FormData。 - 文件 POST 到后端
/upload。 - 后端存储临时文件,再通过
node-ssh传输到远程服务器。 - 删除临时文件,完成上传。
优缺点对比
前端
- webkitdirectory:兼容更好,但交互有限。
- File System Access API:交互灵活,但兼容性差。
后端
- 采用 express + multer,简单易用。
- 借助 node-ssh,实现自动化远程部署。
总结
- 如果项目需要支持更多浏览器,推荐 webkitdirectory。
- 如果项目环境可控,推荐 File System Access API,更灵活。
- 后端使用 Node.js + node-ssh,能快速实现从前端到服务器的自动化传输。
该方案特别适合 批量文件上传、静态资源部署、远程备份 等场景。
《前端读取文件夹并通过 SSH 上传:完整实现方案 ✅》 是转载文章,点击查看原文。
