利用 XMLHttpRequest 或 fetch API 监听上传进度事件,推荐使用 axios(浏览器端)或浏览器原生 API
原生 XMLHttpRequest 方案
// 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append('file', file);
// 监听上传进度事件
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
updateProgressBar(percentComplete); // 更新进度条 UI
}
});
xhr.addEventListener('load', () => {
console.log('上传完成');
});
xhr.addEventListener('error', () => {
console.log('上传失败');
});
xhr.open('POST', '/upload');
xhr.send(formData);
Fetch API 方案
async function uploadWithProgress(file, url) {
const xhr = new XMLHttpRequest();
return new Promise((resolve, reject) => {
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
console.log(`上传进度: ${percent}%`);
}
};
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject(new Error('上传失败'));
const formData = new FormData();
formData.append('file', file);
xhr.open('POST', url);
xhr.send(formData);
});
}
Axios 方案
import axios from 'axios';
async function uploadFile(file) {
const formData = new FormData();
formData.append('file', file);
try {
const response = await axios.post('/upload', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
// 关键配置:启用上传进度监听
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
updateProgress(percentCompleted);
}
});
return response.data;
} catch (error) {
console.error('上传失败:', error);
}
}
// UI 更新函数示例
function updateProgress(percent) {
const progressBar = document.getElementById('progress-bar');
const progressText = document.getElementById('progress-text');
progressBar.style.width = `${percent}%`;
progressText.textContent = `${percent}%`;
if (percent >= 100) {
progressText.textContent = '上传完成';
}
}
<!-- HTML 结构 -->
<div class="upload-container">
<input type="file" id="file-input" />
<button id="upload-btn">上传文件</button>
<div class="progress-container">
<div class="progress-bar" id="progress-bar"></div>
<span class="progress-text" id="progress-text">0%</span>
</div>
</div>
/* CSS 样式 */
.progress-container {
width: 300px;
height: 20px;
background-color: #f0f0f0;
border-radius: 10px;
margin-top: 10px;
overflow: hidden;
position: relative;
}
.progress-bar {
height: 100%;
background: linear-gradient(90deg, #4caf50, #8bc34a);
width: 0%;
transition: width 0.3s ease;
}
.progress-text {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
color: #333;
}
评论区