概述
chrome浏览器提供了多种方式让web应用读取本地文件,从传统的文件输入到现代的文件系统访问api。这些技术为web应用带来了接近原生应用的文件处理能力。
提示: 出于安全考虑,浏览器限制了web应用直接访问本地文件系统。所有文件操作都需要用户主动授权。
主要技术方案
- filereader api - 最常用的文件读取方式
- file system access api - chrome 86 的新特性
- 拖拽api - 提供更好的用户体验
- clipboard api - 读取剪贴板中的文件
filereader api
filereader api是最基础也是最广泛支持的文件读取方式,它允许web应用异步读取存储在用户计算机上的文件内容。
基本用法
const fileinput = document.getelementbyid('fileinput');
const reader = new filereader();
fileinput.addeventlistener('change', (e) => {
const file = e.target.files[0];
if (file) {
reader.readastext(file);
}
});
reader.onload = (e) => {
console.log('文件内容:', e.target.result);
};
reader.onerror = (e) => {
console.error('读取错误:', e.target.error);
};
读取方法对比
| 方法 | 用途 | 返回类型 |
|---|---|---|
| readastext() | 读取文本文件 | string |
| readasdata | 读取为base64 | string |
| readasarraybuffer() | 读取二进制数据 | arraybuffer |
| readasbinarystring() | 读取二进制字符串 | string |
file system access api
file system access api是chrome 86 引入的新特性,它提供了更强大的文件系统访问能力,允许web应用直接读写本地文件。
注意: file system access api目前仅在基于chromium的浏览器中支持,且需要https环境。
打开文件
async function openfile() {
try {
const [filehandle] = await window.showopenfilepicker();
const file = await filehandle.getfile();
const contents = await file.text();
console.log('文件内容:', contents);
} catch (err) {
console.error('打开文件失败:', err);
}
}
保存文件
async function savefile(content) {
try {
const filehandle = await window.showsavefilepicker();
const writable = await filehandle.createwritable();
await writable.write(content);
await writable.close();
console.log('文件保存成功');
} catch (err) {
console.error('保存文件失败:', err);
}
}
拖拽上传
拖拽api提供了更直观的文件上传方式,用户可以直接将文件拖拽到页面指定区域。
实现拖拽上传
const dropzone = document.getelementbyid('dropzone');
dropzone.addeventlistener('dragover', (e) => {
e.preventdefault();
dropzone.classlist.add('drag-over');
});
dropzone.addeventlistener('dragleave', () => {
dropzone.classlist.remove('drag-over');
});
dropzone.addeventlistener('drop', (e) => {
e.preventdefault();
dropzone.classlist.remove('drag-over');
const files = e.datatransfer.files;
handlefiles(files);
});
function handlefiles(files) {
array.from(files).foreach(file => {
console.log('文件名:', file.name);
console.log('文件大小:', file.size);
console.log('文件类型:', file.type);
});
}
安全考虑
在处理本地文件时,必须考虑以下安全因素:
- 始终验证文件类型和大小
- 不要执行用户上传的脚本文件
- 使用csp策略限制资源加载
- 对敏感操作进行二次确认
- 及时释放文件资源
文件类型验证
function validatefile(file) {
const allowedtypes = ['image/jpeg', 'image/png', 'text/plain'];
const maxsize = 5 * 1024 * 1024; // 5mb
if (!allowedtypes.includes(file.type)) {
throw new error('不支持的文件类型');
}
if (file.size > maxsize) {
throw new error('文件大小超过限制');
}
return true;
}
在线演示
试试下面的演示,体验chrome读取本地文件的功能:
方法一:点击选择文件
方法二:拖拽文件到此处
将文件拖拽到这里
支持 .txt, .json, .csv 文件
文件内容预览:
等待选择文件...