js实现文件上传功能
使用HTML表单和JavaScript实现文件上传
创建一个简单的HTML表单,使用<input type="file">元素让用户选择文件。通过JavaScript监听表单提交事件,处理文件上传逻辑。
<input type="file" id="fileInput">
<button onclick="uploadFile()">上传文件</button>
function uploadFile() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (!file) {
alert('请选择文件');
return;
}
const formData = new FormData();
formData.append('file', file);
fetch('/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log('上传成功:', data))
.catch(error => console.error('上传失败:', error));
}
使用XMLHttpRequest实现文件上传
对于需要更精细控制的场景,可以使用XMLHttpRequest对象来实现文件上传,并监听上传进度。
function uploadWithXHR() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
console.log(`上传进度: ${percent}%`);
}
});
xhr.addEventListener('load', () => {
console.log('上传完成');
});
xhr.addEventListener('error', () => {
console.error('上传出错');
});
xhr.open('POST', '/upload', true);
const formData = new FormData();
formData.append('file', file);
xhr.send(formData);
}
使用第三方库实现文件上传
对于更复杂的需求,可以使用第三方库如axios或Dropzone.js简化开发过程。
使用axios上传文件:
import axios from 'axios';
async function uploadWithAxios() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
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 percent = Math.round((progressEvent.loaded / progressEvent.total) * 100);
console.log(`上传进度: ${percent}%`);
}
});
console.log('上传成功:', response.data);
} catch (error) {
console.error('上传失败:', error);
}
}
实现多文件上传
支持用户一次选择多个文件并上传:
<input type="file" id="multiFileInput" multiple>
<button onclick="uploadMultipleFiles()">上传多个文件</button>
function uploadMultipleFiles() {
const fileInput = document.getElementById('multiFileInput');
const files = fileInput.files;
if (files.length === 0) {
alert('请选择文件');
return;
}
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('files', files[i]);
}
fetch('/upload-multiple', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log('上传成功:', data))
.catch(error => console.error('上传失败:', error));
}
文件验证和限制
在上传前对文件进行验证,包括大小、类型等限制:
function validateAndUpload() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
// 验证文件是否存在
if (!file) {
alert('请选择文件');
return;
}
// 验证文件类型
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
if (!allowedTypes.includes(file.type)) {
alert('只支持JPEG, PNG和PDF文件');
return;
}
// 验证文件大小 (5MB限制)
const maxSize = 5 * 1024 * 1024;
if (file.size > maxSize) {
alert('文件大小不能超过5MB');
return;
}
// 验证通过,执行上传
uploadFile(file);
}
显示上传进度和结果
为用户提供上传进度反馈和结果展示:
<div id="progressContainer" style="display: none;">
<progress id="uploadProgress" value="0" max="100"></progress>
<span id="progressText">0%</span>
</div>
<div id="resultContainer"></div>
function uploadWithProgress() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const progressContainer = document.getElementById('progressContainer');
const progressBar = document.getElementById('uploadProgress');
const progressText = document.getElementById('progressText');
const resultContainer = document.getElementById('resultContainer');
progressContainer.style.display = 'block';
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
progressBar.value = percent;
progressText.textContent = `${percent}%`;
}
});
xhr.addEventListener('load', () => {
resultContainer.innerHTML = '<p style="color: green;">上传成功</p>';
progressContainer.style.display = 'none';
});
xhr.addEventListener('error', () => {
resultContainer.innerHTML = '<p style="color: red;">上传失败</p>';
progressContainer.style.display = 'none';
});
xhr.open('POST', '/upload', true);
const formData = new FormData();
formData.append('file', file);
xhr.send(formData);
}
处理服务器响应
处理服务器返回的各种响应情况:
function uploadAndHandleResponse() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
const resultContainer = document.getElementById('resultContainer');
fetch('/upload', {
method: 'POST',
body: file
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP错误! 状态: ${response.status}`);
}
return response.json();
})
.then(data => {
resultContainer.innerHTML = `
<p>上传成功!</p>
<p>文件名: ${data.fileName}</p>
<p>文件大小: ${data.fileSize} bytes</p>
<p>文件URL: <a href="${data.fileUrl}" target="_blank">${data.fileUrl}</a></p>
`;
})
.catch(error => {
resultContainer.innerHTML = `<p>上传失败: ${error.message}</p>`;
});
}






