js实现上传文件
文件上传的基本实现
使用HTML的<input type="file">元素配合JavaScript的File API可以实现文件上传功能。
<input type="file" id="fileInput">
<button id="uploadButton">上传文件</button>
document.getElementById('uploadButton').addEventListener('click', function() {
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
if (file) {
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));
}
});
多文件上传实现
通过添加multiple属性允许选择多个文件,并遍历文件列表进行上传。
<input type="file" id="multiFileInput" multiple>
document.getElementById('uploadButton').addEventListener('click', function() {
const fileInput = document.getElementById('multiFileInput');
const files = fileInput.files;
if (files.length > 0) {
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append('files[]', files[i]);
}
fetch('/multi-upload', {
method: 'POST',
body: formData
})
.then(/* 处理响应 */);
}
});
上传进度监控
使用XMLHttpRequest可以监控文件上传进度。

function uploadWithProgress(file) {
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append('file', file);
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
const percentComplete = (e.loaded / e.total) * 100;
console.log(`上传进度: ${percentComplete}%`);
}
});
xhr.open('POST', '/upload', true);
xhr.send(formData);
}
文件类型和大小验证
在上传前对文件进行验证。
const MAX_SIZE = 10 * 1024 * 1024; // 10MB
const ALLOWED_TYPES = ['image/jpeg', 'image/png'];
function validateFile(file) {
if (!ALLOWED_TYPES.includes(file.type)) {
alert('不支持的文件类型');
return false;
}
if (file.size > MAX_SIZE) {
alert('文件大小超过限制');
return false;
}
return true;
}
拖放上传实现
通过监听拖放事件实现更友好的上传体验。

<div id="dropArea" style="border: 2px dashed #ccc; padding: 20px;">
拖放文件到这里上传
</div>
const dropArea = document.getElementById('dropArea');
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
['dragenter', 'dragover'].forEach(eventName => {
dropArea.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, unhighlight, false);
});
function highlight() {
dropArea.style.borderColor = 'blue';
}
function unhighlight() {
dropArea.style.borderColor = '#ccc';
}
dropArea.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
if (files.length) {
// 处理上传
}
}
文件预览实现
在上传前显示文件预览。
function showPreview(file) {
const preview = document.getElementById('preview');
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = function(e) {
preview.innerHTML = `<img src="${e.target.result}" style="max-width: 200px;">`;
};
reader.readAsDataURL(file);
} else {
preview.textContent = `文件名: ${file.name}`;
}
}
分片上传实现
对于大文件,可以采用分片上传策略。
function uploadInChunks(file, chunkSize = 1024 * 1024) {
const totalChunks = Math.ceil(file.size / chunkSize);
let chunkNumber = 0;
function uploadChunk() {
const start = chunkNumber * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('chunkNumber', chunkNumber);
formData.append('totalChunks', totalChunks);
formData.append('filename', file.name);
return fetch('/upload-chunk', {
method: 'POST',
body: formData
})
.then(response => {
chunkNumber++;
if (chunkNumber < totalChunks) {
return uploadChunk();
}
return response.json();
});
}
return uploadChunk();
}






