文件上传
获取文件数据
前端实现文件上传,获取文件的方式主要有两种:
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
值发生变化每次执行完上传逻辑后清空 value
值 fileNode.value = ""