The File System Access API:根据文件系统API自定义Input Upload
1.前言
先说一下功能需求背景,需要在浏览器端选择文件夹后按遍历文件夹中的所有文件(包含文件夹嵌套文件),项目使用的前端UI组件是React Ant Design,使用Input Upload之后,文件夹可以选取但需要配合action必传字段将文件夹里的所有文件上传后才能预览,并且浏览器Dialog弹出之后显示的“上传”字样,会让用户产生误解,因此开始的调研之路。
2.File System Access API介绍
什么是File System Access API呢?
一开始我也是有点不理解,翻译成中文就是文件系统访问API(在以前被称为Native File System API本地文件系统API,更久之前称为Writeable Files API可写文件API),它可以让开发人员能够开发出特别友好的网络App,能够与用户的本地设备文件进行友好交互,例如集成编辑器,照片和视频编辑软件,文本编辑器等等。在用户授权网站应用后,该文件系统API允许读取和保存用户本地设备文件和文件夹,除此之外文件系统访问 API 还提供了打开目录和枚举其内容的能力。
目前,Windows、macOS、Chrome OS 和 Linux 上的大多数 Chromium 浏览器都支持文件系统访问 API。
3.File System Access API
File System Access API 一共可分为三大类
- Window.showOpenFilePicker() 打开文件选取窗口
- Window.showSaveFilePicker() 打开文件保存窗口
- Window.showDirectoryPicker() 打开文件夹选取窗口
根据需求这里主要使用的Window.showDirectoryPicker()
4.代码示例
<input id='select' type="button" value="选择文件夹">
document.getElementById("select").addEventListener('click', async function onClickHandler(e) {
try {
const directoryHandle = await window.showDirectoryPicker({
startIn: "desktop"
});
const name = directoryHandle.name;
const files = await listAllFilesAndDirs(directoryHandle, name);
console.log(files, 'files');
} catch (e) {
console.log(e);
}
});
async function listAllFilesAndDirs(dirHandle, path) {
const files = [];
for await (let [name, handle] of dirHandle) {
const {
kind
} = handle;
if (handle.kind === 'directory') {
const newPath = `${path}/${name}`;
files.push(...await listAllFilesAndDirs(handle, newPath));
} else {
// console.log(handle, "name");
const file = await handle.getFile();
console.log(`${path}/${file.name}`);
file.relativePath = `${path}/${file.name}`;
if (filterTypes(file)) files.push(file);
}
}
return files;
}
function filterTypes(file, types = ['image/jpeg', 'video/mp4']) {
if (!files) {
return false;
}
if (types.includes(file.type)) {
return true;
}
return false;
}
5.总结
这只是本人的一点心得,希望能够和各位大牛~能过够多多交流学习心得,请留下个小心心吧
参考文章:The File System Access API: simplifying access to local files