主题
最基本的文件上传
文件上传的起点不是“怎么发请求”,而是“怎么把用户选择的文件拿到前端代码里”。
最基本入口:input[type="file"]
浏览器里最基础的文件选择方式是:
html
<input type="file" id="fileInput" />用户选择后,可以在 change 事件里拿到文件列表:
js
const fileInput = document.getElementById('fileInput')
fileInput.addEventListener('change', (event) => {
const files = event.target.files
console.log(files)
})这里拿到的是 FileList,其中每一项通常都是 File 对象。
单文件和多文件
默认情况下通常是单文件选择。
如果需要多文件:
html
<input type="file" id="fileInput" multiple />这时 files 里可能会有多个文件。
拿到文件后通常会做什么
最常见的后续步骤包括:
- 展示文件名、大小、类型
- 做前端校验
- 组装成
FormData - 发起上传请求
所以“文件上传”一般可以拆成两段:
- 选择文件
- 发送文件
自定义上传按钮
原生文件输入框可用,但样式通常不够灵活,所以常见做法是隐藏原生控件,再用 label 触发选择:
html
<input type="file" id="fileInput" hidden />
<label for="fileInput" class="upload-btn">选择文件</label>css
.upload-btn {
display: inline-flex;
padding: 6px 12px;
border-radius: 6px;
background: #1677ff;
color: #fff;
cursor: pointer;
}这种方式的关键点是:
- 不要丢掉原生输入框能力
- 只是把触发入口换成更可控的 UI
拖拽上传
除了点击选择,还可以让用户把文件拖进页面区域。
html
<div id="dropZone">拖拽文件到此区域上传</div>js
const dropZone = document.getElementById('dropZone')
dropZone.addEventListener('dragover', (event) => {
event.preventDefault()
})
dropZone.addEventListener('drop', (event) => {
event.preventDefault()
const files = event.dataTransfer.files
console.log(files)
})这里最关键的是:
dragover要阻止默认行为drop也要阻止默认行为
否则浏览器可能会直接打开文件,而不是交给页面处理。
拖拽上传适合什么
更适合:
- 图片上传区
- 附件管理面板
- 桌面类操作感较强的页面
但它通常不是唯一入口,实际页面里常常会和点击选择并存。
使用时要注意什么
文件输入框的值不能随便模拟
出于安全原因,浏览器不会让脚本任意伪造本地文件路径。
只拿到文件不等于已经上传
File / FileList 只是前端拿到了文件对象,还没有发生网络传输。
校验通常要尽早做
常见校验包括:
- 文件类型
- 文件大小
- 数量限制
这些通常在真正发送前就做。
使用建议
- 最基础的文件上传入口优先从
input[type="file"]理解。 - 自定义样式时,优先保留原生输入框行为,而不是完全重造。
- 拖拽上传适合作为增强入口,不一定适合作为唯一入口。
- 把“选择文件”和“发送文件”分成两步理解,后续上传流程会更清晰。
