js实现图片上传
图片上传的基本实现
使用HTML的<input type="file">元素配合JavaScript的File API可以实现图片上传功能。HTML部分需要创建一个文件选择输入框和一个用于显示预览的图片元素。
<input type="file" id="upload" accept="image/*">
<img id="preview" src="#" alt="Preview">
监听文件选择变化
通过监听input元素的change事件获取用户选择的文件。使用FileReader对象读取文件内容并显示预览。
document.getElementById('upload').addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file.type.match('image.*')) {
alert('请选择图片文件');
return;
}
const reader = new FileReader();
reader.onload = function(e) {
document.getElementById('preview').src = e.target.result;
};
reader.readAsDataURL(file);
});
上传图片到服务器
使用FormData对象构造表单数据,通过fetch或XMLHttpRequest发送到服务器。这里展示使用fetch的现代方法。
function uploadImage(file) {
const formData = new FormData();
formData.append('image', file);
fetch('/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log('上传成功:', data))
.catch(error => console.error('上传失败:', error));
}
// 在change事件处理中调用
document.getElementById('upload').addEventListener('change', function(e) {
const file = e.target.files[0];
uploadImage(file);
});
图片压缩处理
对于大图上传,可以使用Canvas API进行压缩。创建一个临时Canvas元素,调整尺寸和质量后转换为Blob对象上传。
function compressImage(file, maxWidth = 800, quality = 0.7) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = function(e) {
const img = new Image();
img.onload = function() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
let width = img.width;
let height = img.height;
if (width > maxWidth) {
height = Math.round((height * maxWidth) / width);
width = maxWidth;
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob(resolve, 'image/jpeg', quality);
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
});
}
// 使用压缩后的图片上传
compressImage(file).then(blob => {
uploadImage(blob);
});
多图上传实现
通过添加multiple属性允许选择多个文件,遍历文件列表逐个处理。
<input type="file" id="upload" accept="image/*" multiple>
<div id="previews"></div>
document.getElementById('upload').addEventListener('change', function(e) {
const files = e.target.files;
Array.from(files).forEach(file => {
if (!file.type.match('image.*')) return;
const reader = new FileReader();
reader.onload = function(e) {
const img = document.createElement('img');
img.src = e.target.result;
img.style.maxWidth = '200px';
document.getElementById('previews').appendChild(img);
};
reader.readAsDataURL(file);
});
});
进度显示
使用XMLHttpRequest的upload事件可以跟踪上传进度,创建进度条显示上传状态。
function uploadWithProgress(file) {
const xhr = new XMLHttpRequest();
const formData = new FormData();
formData.append('image', file);
xhr.upload.addEventListener('progress', function(e) {
const percent = Math.round((e.loaded / e.total) * 100);
console.log(`上传进度: ${percent}%`);
// 更新UI进度条
});
xhr.open('POST', '/upload');
xhr.send(formData);
}
注意事项
- 服务器端需要配置相应的接口接收文件,常见框架如Express、Django等都提供文件处理中间件
- 生产环境应考虑添加文件大小限制、类型校验等安全措施
- 移动端可能需要额外处理相机拍摄的图片方向问题
- 对于大量图片上传,建议实现分片上传或断点续传功能







