文件上传是Web应用中的常见功能,通常涉及前端选择文件、本地预览,以及后端接收并存储文件。现代JavaScript API让这个过程变得比以往更直观。
![图片[1]-如何实现文件上传和预览?-速码派](http://www.sumapai.com/wp-content/uploads/2026/01/fe0a68d1547c44d1beb58ffb79cef435_tplv-tb4s082cfz-aigc_resize_1080_1080-1-1024x683.webp)
前端选择与读取文件
核心是利用<input type="file">元素,它允许用户从设备中选择文件。通过监听其change事件,我们可以获取到用户选择的文件列表(FileList对象)。
<input type="file" id="fileInput" accept="image/*">
<img id="preview" src="#" alt="预览" style="display:none; max-width: 300px;">
const fileInput = document.getElementById('fileInput');
const preview = document.getElementById('preview');
fileInput.addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
// 创建文件预览
const reader = new FileReader();
reader.onload = function(event) {
preview.src = event.target.result;
preview.style.display = 'block';
};
reader.readAsDataURL(file); // 将文件读取为Data URL
});
FileReader对象可以异步读取文件内容。readAsDataURL方法将文件转换为Base64编码的URL,非常适合用于在<img>标签中直接预览图片。对于其他文件类型(如PDF),预览逻辑会更复杂。
使用FormData进行文件上传
将文件发送到服务器的最标准方式是使用FormData对象。它可以模拟表单提交,非常适合传输文件数据。
async function uploadFile(file) {
const formData = new FormData();
formData.append('file', file); // 'file'是服务器期望的字段名
formData.append('userId', '123'); // 可以附加其他数据
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
// 注意:不要手动设置 Content-Type,浏览器会自动添加正确的 multipart/form-data 边界
});
const result = await response.json();
console.log('上传成功', result);
} catch (error) {
console.error('上传失败', error);
}
}
// 在文件选择后调用
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (file) {
uploadFile(file);
}
});
使用FormData时,无需手动设置请求头Content-Type,浏览器会自动处理。这是上传二进制文件(如图片、视频)的推荐方式。
实现拖拽上传
提升用户体验的一个方法是支持拖拽。通过监听容器的dragover、dragleave和drop事件可以实现。
<div id="dropZone" style="border: 2px dashed #ccc; padding: 50px; text-align: center;">
将文件拖拽到此区域
</div>
const dropZone = document.getElementById('dropZone');
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.style.borderColor = 'blue';
});
dropZone.addEventListener('dragleave', () => {
dropZone.style.borderColor = '#ccc';
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.style.borderColor = '#ccc';
const file = e.dataTransfer.files[0];
if (file) {
previewFile(file);
uploadFile(file);
}
});
在drop事件中,通过e.dataTransfer.files可以获取到拖放的文件列表。
后端需要相应的API来接收multipart/form-data格式的数据(例如使用Node.js的multer中间件或Python的Flask框架)。对于大文件,还需要考虑分片上传和进度跟踪。前端通过XMLHttpRequest或fetch的响应可以获取上传进度,为用户提供反馈。






















暂无评论内容