Skip to main content

文件上传

获取文件数据

前端实现文件上传,获取文件的方式主要有两种:

input 选择文件

<input type="button" id="btn">点击</input>
<input type="file" id="file" style='display:none' />
// ...
const btnNode = document.getElementById('btn');
const fileNode = document.getElementById('file');
btnNode.addEventListener("click", function (e) {
fileNode.click();
}, false);

fileNode.addEventListener('change',function (e) {
// e.target.files / fileNode.files 可以拿到文件数据
// 可以通过 FileReader 读取文件内容,输出到预览窗口
const fileReader = new FileReader();
fileReader.readAsText(e.files[0]);
fileReader.onload(file => {
console.log(file);
});
}, false);

拖拽文件

<div id="unload" draggable="true">
将文件拖到此处上传
</div>;
// ...
let unloadNode = document.getElementById("unload");
unloadNode.addEventListener(
"dragenter",
(e) => {
// 禁用浏览器默认事件
e.preventDefault();
e.stopPropagation();
},
false
);
unloadNode.addEventListener(
"dragover",
(e) => {
e.preventDefault();
e.stopPropagation();
},
false
);
unloadNode.addEventListener(
"drop",
function (e) {
e.preventDefault();
e.stopPropagation(); // e.dataTransfer.files
//可以拿到文件数据
},
false
);

以上两种交互的目的是获得文件数据,是一个 File 对象,之后借助 FormData 包装文件数据后通过异步请求发送到后端

const formData = new FormData();
formData.add("file", e.target.files[0]);
// fetch
fetch("http://localhost:8080/upload", {
method: "POST", // 也可以是 PUT 请求
body: formData,
})
.then((res) => {})
.catch((err) => {});
// axios
// axios.post("http://localhost:8000/upload", formData);

fetch 会自动帮助我们添加请求头 Content-Type: form-data 和边界数据 boundary,详见 MDN-Content-Type

[WIP]上传多个文件

其它问题

相同文件只能触发一次 onChange

input[file] change 事件触发的判断标准是 value 值发生变化每次执行完上传逻辑后清空 valuefileNode.value = ""