React JS中如何选择文件夹并获取目标目录的本地路径
核心限制说明
你之前的写法没达到预期有两个根本原因:
webkitdirectory/mozdirectory/directory这几个属性的原生逻辑就是:选中文件夹后自动递归遍历所有子文件,返回的文件列表是目录下所有子文件对象,本身就不会直接返回文件夹条目- 纯网页(浏览器)环境受安全沙箱强制限制,没有任何合规方案可以获取用户本地文件/文件夹的真实系统绝对路径(也就是你要的
C:\Documents\Test格式路径),所有网页能拿到的只有浏览器生成的沙箱内相对路径、Blob虚拟路径。只有Electron、Tauri这类桌面端套壳应用,才能调用系统原生接口拿到真实本地路径。
可落地实现方案
方案1:现代浏览器纯Web场景(Chrome/Edge 86+、Firefox 111+支持)
用官方File System Access API直接唤起目录选择窗口,不需要遍历子文件,不会返回子文件路径,是目前Web端最符合交互预期的方案:
<button id="selectDirBtn">选择文件夹</button> <script> const selectDirBtn = document.getElementById('selectDirBtn'); selectDirBtn.addEventListener('click', async () => { try { // 直接唤起系统原生目录选择窗口 const dirHandle = await window.showDirectoryPicker({ mode: 'read' // 仅需要读权限,如需写入可改为'readwrite' }); // 可直接获取文件夹名称,dirHandle是可直接操作目录的句柄,支持后续读写目录内文件 console.log('选中文件夹名称:', dirHandle.name); // 注意:纯Web环境下此处拿不到C:\开头的真实系统绝对路径,这是浏览器安全限制,无法绕过 } catch (err) { // 用户主动取消选择时会抛出AbortError,不需要额外处理 if (err.name !== 'AbortError') console.error('选择失败:', err); } }) </script>
方案2:Electron桌面端场景(可获取真实系统绝对路径)
如果你的项目是Electron开发的桌面应用,直接调用原生dialog模块即可,选中后直接返回文件夹绝对路径,完全不会返回子文件路径,完全匹配你的需求:
主进程代码
const { ipcMain, dialog } = require('electron'); // 注册目录选择IPC处理函数 ipcMain.handle('select-local-dir', async () => { const selectResult = await dialog.showOpenDialog({ properties: ['openDirectory'] // 配置为仅选择文件夹,不允许选文件 }); if (!selectResult.canceled && selectResult.filePaths.length) { // 直接返回选中文件夹的真实绝对路径,格式如 C:\Documents\Test return selectResult.filePaths[0]; } return null; })
渲染进程代码
const { ipcRenderer } = require('electron'); const selectDirBtn = document.getElementById('selectDirBtn'); selectDirBtn.addEventListener('click', async () => { const dirPath = await ipcRenderer.invoke('select-local-dir'); if (dirPath) { console.log('选中的文件夹绝对路径:', dirPath); // 此处拿到的就是纯文件夹路径,不会包含任何子文件名 } })
方案3:旧浏览器降级方案(基于webkitdirectory)
如果需要兼容不支持File System Access API的旧浏览器,可以用你之前写的input标签实现,不需要遍历所有子文件,从第一个文件的相对路径里拆分出文件夹名即可。注意:这个方案依然拿不到真实系统绝对路径。
<!-- 隐藏原生input,用自定义按钮触发 --> <input type="file" id="dirInput" webkitdirectory mozdirectory directory hidden> <button id="selectDirBtn">选择文件夹</button> <script> const dirInput = document.getElementById('dirInput'); const selectDirBtn = document.getElementById('selectDirBtn'); selectDirBtn.addEventListener('click', () => dirInput.click()); dirInput.addEventListener('change', (e) => { const fileList = e.target.files; if (fileList.length) { // 取第一个文件的相对路径,拆分后第一段就是选中的文件夹名 const firstFileRelativePath = fileList[0].webkitRelativePath; const selectedDirName = firstFileRelativePath.split('/')[0]; console.log('选中文件夹名:', selectedDirName); } // 清空input值,保证下次选择相同文件夹也能触发change事件 e.target.value = ''; }) </script>
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

