javascript文件上传
交互
multiple
点击上传多个文件 用户可以选择多个文件,然后文件列表会显示出来。需要注意的是,文件的选择是通过<input type="file" multiple>
标签来实现的,其中multiple
属性允许选择多个文件。
const { useState, useEffect, ChangeEvent } = React;
export default () => {
const [files, setFiles] = useState([]);
const [fileList, setFileList] = useState([]);
const handleChange = (e) => {
const files = e.target.files;
if (files) {
setFiles(Array.from(files));
}
};
useEffect(() => {
const fileList = files.map((file) => file.name);
setFileList(fileList);
}, [files]);
return (
<div>
<input type="file" multiple onChange={handleChange} />
<ul>
{fileList.map((file, index) => (
<li key={index}>{file}</li>
))}
</ul>
</div>
);
};
odirectory
点击上传文件夹 允许用户上传整个文件夹,而不仅仅是单个文件。使用<input type="file" webkitdirectory mozdirectory odirectory>
标签来启用文件夹上传功能。在处理时,代码会检查文件是否为文件夹,然后递归读取文件夹中的文件列表。
webkitdirectory
、mozdirectory
和odirectory
是用于HTML
文件输入元素<input type="file">
的属性,用于启用文件夹上传功能。它们是浏览器厂商引入的一些非标准属性,因此在不同浏览器中的支持程度可能会有所不同。
webkitdirectory
:
支持浏览器: WebKit
内核的浏览器,如Google Chrome
和Safari
。
作用: 当设置webkitdirectory
属性时,文件输入框会打开一个文件选择对话框,允许用户选择文件夹而不仅仅是单个文件。这允许用户选择整个文件夹中的所有文件,而不必一个一个地选择。
mozdirectory
:
支持浏览器: Mozilla Firefox
浏览器。
作用: 类似于webkitdirectory
,mozdirectory
属性用于启用文件夹上传功能。它允许用户在Firefox
浏览器中选择整个文件夹进行上传。
odirectory
:
支持浏览器: 这是Opera
浏览器引入的一个属性。
作用: 类似于前两者,odirectory
属性用于启用文件夹上传功能。用户可以在Opera浏览器中选择整个文件夹。
需要注意的是,由于这些属性不是HTML标准的一部分,因此在不同浏览器中的支持可能不稳定。它们主要用于特定浏览器内核的实现,因此在跨浏览器应用程序中使用时,需要小心检查并处理不同浏览器的兼容性。在现代Web开发中,通常使用其他更标准的方法,如使用JavaScript
来处理文件上传和文件夹选择,以确保跨浏览器兼容性。
const { useState, useEffect, ChangeEvent } = React;
export default () => {
const [files, setFiles] = useState([]);
const [fileList, setFileList] = useState([]);
const handleChange = (e) => {
const files = e.target.files;
if (files) {
setFiles(Array.from(files));
}
};
useEffect(() => {
const fileList = files.map((file) => file.name);
setFileList(fileList);
}, [files]);
return (
<div>
<input type="file" webkitdirectory mozdirectory odirectory onChange={handleChange} />
<ul>
{fileList.map((file, index) => (
<li key={index}>{file}</li>
))}
</ul>
</div>
);
};
dataTransfer
拖拽上传文件和文件夹用户可以将文件或文件夹拖拽到指定区域进行上传。代码使用onDragOver
和onDrop
事件来处理拖拽操作,并通过e.dataTransfer.items
来获取拖拽的文件和文件夹列表。
const { useState, useEffect, ChangeEvent } = React;
export default () => {
const [files, setFiles] = useState([]);
const [fileList, setFileList] = useState([]);
const handleChange = (e) => {
const files = e.target.files;
if (files) {
setFiles(Array.from(files));
}
};
const handleDragOver = (e) => {
e.preventDefault();
};
const handleDrop = (e) => {
e.preventDefault();
const files = e.dataTransfer.items;
// 判断是否为文件夹
for (const item of files) {
const entry = item.webkitGetAsEntry();
if (entry.isDirectory) {
console.log('is directory');
entry.createReader().readEntries((entries) => {
console.log(entries);
const fileList = entries.map((entry) => entry.name);
setFileList(fileList);
});
} else {
console.log('is file');
entry.file((file) => {
console.log(file.name);
setFiles([file]);
});
}
}
};
useEffect(() => {
const fileList = files.map((file) => file.name);
setFileList(fileList);
}, [files]);
return (
<div>
<input type="file" multiple onChange={handleChange} onDragOver={handleDragOver} onDrop={handleDrop} />
<ul>
{fileList.map((file, index) => (
<li key={index}>{file}</li>
))}
</ul>
</div>
);
};
如何实现多文件上传
- 把选择的文件放到一个数组里
files
一次性发送到服务器,服务器接收到后,再一次性处理 - 把选择的文件形成不同的请求,每个请求只处理一个文件一般会选择第二种,第一种方式,如果文件很多,其中一个文件上传失败,需要重新上传所有文件,很难保证对每一个文件的独立控制。第二种方式,需要控制并发数,如果并发数太大,可能会导致服务器崩溃,可以对于每个文件进行单独的控制,比如上传进度,上传取消等。
progress
上传进度使用XMLHttpRequest
对象来发送文件,并通过xhr.upload.onprogress
事件来监听上传进度。上传进度以百分比形式显示给用户。
const { useState } = React;
export default () => {
const [progress, setProgress] = useState(0);
const handleUpload = (e) => {
const file = e.target.files?.[0];
if (file) {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percentComplete = Math.round((event.loaded / event.total) * 100);
setProgress(percentComplete);
}
};
xhr.send(file);
}
};
return (
<div>
<input type="file" onChange={handleUpload} />
<p>{progress}%</p>
</div>
);
}
如何实现上传进度追踪
用户可以点击Cancel
按钮来中止上传操作,这对于用户体验和控制非常有用。代码使用xhr.abort()
方法来中止上传操作。
const { useState } = React;
export default () => {
const [progress, setProgress] = useState(0);
const [xhr, setXhr] = useState(null);
const handleUpload = (e) => {
const file = e.target.files?.[0];
if (file) {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percentComplete = Math.round((event.loaded / event.total) * 100);
setProgress(percentComplete);
}
};
xhr.send(file);
setXhr(xhr);
}
};
const handleCancel = () => {
if (xhr) {
xhr.abort();
setXhr(null);
setProgress(0);
}
};
return (
<div>
<input type="file" onChange={handleUpload} />
<p>{progress}%</p>
{xhr && <button onClick={handleCancel}>Cancel</button>}
</div>
);
}