在用户本地设备上选择文件并与之互动是 最常用的网络功能它允许用户选择文件和 将其上传到服务器,例如在分享照片或提交税费信息时 文档。它还允许网站无需 通过网络传输数据本页将介绍如何使用 与文件交互的 JavaScript。
现代 File System Access API
File System Access API 提供了一种在文件内读写文件的方法, 用户本地系统上的目录。适用于大多数基于 Chromium 的 例如 Chrome 和 Edge。如需了解详情,请参阅 File System Access API。
File System Access API 并非与所有浏览器都兼容 建议使用 browser-fs-access 帮助程序库,该库在适用情况下使用新的 API,并且 需要重新采用旧方法。
以传统方式处理文件
本指南将向您介绍如何使用旧版 JavaScript 方法与文件交互。
选择文件
选择文件主要有以下两种方式: HTML 输入元素,并使用 拖放区域。
HTML 输入元素
用户选择文件的最简单方法是使用
<input type="file">
元素,所有主流浏览器都支持这种样式。点击后,用户可以
选择一个或多个文件
multiple
属性。
界面。当用户选择完一个或多个文件后,元素的 change
事件触发。您可以从event.target.files
访问文件列表,
是 FileList
对象。
FileList
中的每一项都是一个 File
对象。
<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
以下示例可让用户使用 系统内置文件选择界面,然后将每个选定文件记录到 控制台。
限制用户可以选择的文件类型
在某些情况下,您可能希望限制用户可以选择的文件类型。对于
例如,图片编辑应用应仅接受图片,而不接受文本文件。设置
文件类型限制、添加
accept
属性指定系统接受的文件类型:
<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">
自定义拖放
在某些浏览器中,<input type="file">
元素也是拖放目标,
让用户能够将文件拖放到您的应用中。不过,这个拖放目标
体积较小,可能难以使用。相反,在您使用
<input type="file">
元素,您可以提供一个大型自定义拖放
。
选择送餐区
拖放 surface 取决于应用的设计。您可能只想使用 将部分窗口设置为落下表面,但您也可以使用整个窗口。
<ph type="x-smartling-placeholder">通过图片压缩应用 Squoosh,用户可以将图片拖动到
窗口,然后点击 select an image 以调用 <input type="file">
元素。无论您选择什么作为放置区域,都要确保用户清楚知道
将文件拖动到该表面上。
定义拖放区
要将某个元素启用为拖放区域,请为
两个事件:dragover
和 drop
。
dragover
事件会更新浏览器界面,以直观地指示
即可创建文件的副本drop
事件会触发
当用户将文件拖放到界面上后。与输入元素一样,
可以访问 event.dataTransfer.files
中的文件列表,该文件是
FileList
对象。每个
FileList
中的项是 File
对象。
const dropArea = document.getElementById('drop-area');
dropArea.addEventListener('dragover', (event) => {
event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});
dropArea.addEventListener('drop', (event) => {
event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});
event.stopPropagation()
和event.preventDefault()
停止浏览器的默认行为,让代码运行。如果没有它们,
否则浏览器就会离开您的网页并打开这些文件
进入浏览器窗口的用户
如需查看现场演示,请参阅自定义拖放。
那目录呢?
遗憾的是,使用 JavaScript 访问目录并没有一种好方法。
webkitdirectory
<input type="file">
元素上的属性可让用户选择目录,
或目录大多数主流浏览器都支持
但 Android 版 Firefox 和 iOS 版 Safari 除外。
如果启用了拖放功能,用户可能会尝试将某个目录拖到
放置区域当拖放事件触发时,它会为File
目录,但不提供对该目录中任何文件的访问权限。
读取文件元数据
File
对象包含有关文件的元数据。大多数浏览器
文件名、文件大小和 MIME 类型
不同的浏览器可能会提供不同或额外的
信息。
function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}
您可以在 input-type-file
中查看实际操作示例。
演示。
读取文件的内容
使用 FileReader
执行以下操作:
将 File
对象的内容读取到内存中。您可以让FileReader
执行以下操作:
将文件读取为数组缓冲区;
数据网址;
或文本:
function readImage(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('image/')) {
console.log('File is not an image.', file.type, file);
return;
}
const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}
此示例会读取用户提供的 File
,然后将其转换为数据
网址,并使用该数据网址在 img
元素中显示图片。
要了解如何验证用户是否已选择图片文件,请参阅
read-image-file
演示。
监控文件读取进度
读取大型文件时,提供一些用户体验告诉用户会很有帮助
读取的进度为此,请使用
progress
事件,由 FileReader
提供。progress
事件有两个属性:
loaded
(读取量)和 total
(读取量)。
function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}
Vincent Botta 的主打图片,来自 Unspin