js实现视频上传
视频上传的基本实现
使用HTML5的<input type="file">元素配合JavaScript的File API可以实现视频上传功能。核心是通过监听文件选择事件获取视频文件对象。
<input type="file" id="videoUpload" accept="video/*">
const videoUpload = document.getElementById('videoUpload');
videoUpload.addEventListener('change', handleVideoUpload);
function handleVideoUpload(event) {
const file = event.target.files[0];
if (!file.type.includes('video/')) {
alert('请选择视频文件');
return;
}
// 处理视频文件
}
视频预览功能
在文件选择后可以立即创建本地预览,无需等待上传完成。使用URL.createObjectURL生成临时URL供<video>元素播放。
function handleVideoUpload(event) {
const file = event.target.files[0];
const videoPreview = document.createElement('video');
videoPreview.controls = true;
videoPreview.src = URL.createObjectURL(file);
document.body.appendChild(videoPreview);
}
分块上传大文件
对于大视频文件,建议使用分块上传技术。通过Blob.prototype.slice方法将文件切割为多个小块。
async function uploadInChunks(file) {
const chunkSize = 5 * 1024 * 1024; // 5MB每块
let offset = 0;
while (offset < file.size) {
const chunk = file.slice(offset, offset + chunkSize);
const formData = new FormData();
formData.append('chunk', chunk);
formData.append('offset', offset);
await fetch('/upload', {
method: 'POST',
body: formData
});
offset += chunkSize;
}
}
进度监控实现
通过XMLHttpRequest的progress事件或Fetch API的ReadableStream可以获取上传进度。
function uploadWithProgress(file) {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
console.log(`上传进度: ${percent}%`);
}
};
const formData = new FormData();
formData.append('video', file);
xhr.send(formData);
}
文件校验处理
上传前应对视频文件进行基本校验,包括文件类型、大小限制等。
function validateVideoFile(file) {
const validTypes = ['video/mp4', 'video/webm', 'video/ogg'];
const maxSize = 500 * 1024 * 1024; // 500MB
if (!validTypes.includes(file.type)) {
throw new Error('不支持的视频格式');
}
if (file.size > maxSize) {
throw new Error('视频文件过大');
}
return true;
}
完整示例代码
<input type="file" id="videoUpload" accept="video/*">
<progress id="uploadProgress" value="0" max="100" style="width: 100%"></progress>
<div id="previewContainer"></div>
<script>
document.getElementById('videoUpload').addEventListener('change', async (event) => {
const file = event.target.files[0];
try {
validateVideoFile(file);
// 预览
const previewUrl = URL.createObjectURL(file);
document.getElementById('previewContainer').innerHTML = `
<video controls style="max-width: 100%">
<source src="${previewUrl}" type="${file.type}">
</video>
`;
// 上传
await uploadWithProgress(file);
} catch (error) {
alert(error.message);
}
});
async function uploadWithProgress(file) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percent = Math.round((event.loaded / event.total) * 100);
document.getElementById('uploadProgress').value = percent;
}
};
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject(new Error('上传失败'));
const formData = new FormData();
formData.append('video', file);
xhr.send(formData);
});
}
</script>
服务器端注意事项
前端实现需配合适当的后端处理:
- 设置正确的CORS头允许跨域上传
- 配置足够大的请求体大小限制
- 实现分块上传的合并逻辑
- 考虑使用云存储服务如AWS S3的直接上传方案







