效果:
缘由:
在前端页面解析,使用原生的input或者el-upload的accept属性只能进行文件类型校验阻止上传,在文件上传选择窗口还是有所有选项(*.*)这个选项,怎么禁用这个浏览器或操作系统自带的文件选择窗口中的所有选项?
思路:
经查阅资料了解,Chrome 86 版本后引入了一项新的 File System API,可以在调用 showOpenFilePicker
方法时指定 excludeAcceptAllOption
参数为 false 来禁用掉“所有文件”。
缺点:兼容性,目前仅 Chrome 86+ 版本支持,其他浏览器都未支持这一特性。
知识抢先看:
File System API
是一种现代的 Web API,允许 Web 应用更直接地访问用户的文件系统。它可以在前端应用中提供类似桌面应用的文件管理功能,支持文件的创建、读写、删除等操作。
- 打开文件选择器:
showOpenFilePicker()
用于打开文件选择器,用户可以选择文件或文件夹。async function openFile() { try { const [fileHandle] = await window.showOpenFilePicker({ types: [ { description: 'Text files', accept: { 'text/plain': ['.txt'] } } ], excludeAcceptAllOption: true, multiple: false }); const file = await fileHandle.getFile(); console.log('Selected file:', file); } catch (error) { console.error('Error:', error); } }
- 读取文件内容:通过
fileHandle.getFile()
可以获得用户选择的文件,之后可以使用 File API 读取文件内容。async function readFile(fileHandle) { const file = await fileHandle.getFile(); const text = await file.text(); console.log('File content:', text); }
- 写入文件内容:
createWritable()
用于获取一个可写入的流,允许将数据写入文件。async function writeFile(fileHandle, content) { const writable = await fileHandle.createWritable(); await writable.write(content); await writable.close(); }
- 保存文件:通过
showSaveFilePicker()
让用户选择保存位置并创建文件。async function saveFile() { const options = { types: [ { description: 'Text files', accept: { 'text/plain': ['.txt'] } } ] }; const fileHandle = await window.showSaveFilePicker(options); await writeFile(fileHandle, 'Hello, world!'); }
- 访问目录:
showDirectoryPicker()
可以让用户选择一个文件夹,并在该文件夹内创建、读取或删除文件。async function openDirectory() { const directoryHandle = await window.showDirectoryPicker(); for await (const entry of directoryHandle.values()) { console.log(entry.kind, entry.name); } }
应用:
使用 showOpenFilePicker
API 实现文件选择,并禁用“所有文件”选项。
<template>
<el-button @click="openFilePicker">自定义文件选择器</el-button>
</template>
<script setup>
async function openFilePicker () {
try {
const [fileHandle] = await window.showOpenFilePicker({
types: [
{
description: '矢量文件',
accept: {
'*/*': ['.kml', '.shp'] // 接受所有 MIME 类型,但限制扩展名
}
}
],
excludeAcceptAllOption: true, // 禁用“所有文件”选项
multiple: false // 限制单个文件
});
const file = await fileHandle.getFile();
console.log('选择文件:', file);
// 实现想要的操作逻辑
} catch (error) {
console.error('文件获取错误:', error);
}
}
</script>