HTML5用上传视频最直接,需加accept="video/*"并用JS校验file.type和文件后缀,大文件须预检体积,用FormData+fetch发送且不设Content-Type,注意Nginx和后端配置。
选视频文件最直接浏览器原生支持视频上传,不需要额外库。关键在于限制类型和校验,避免用户误选非视频文件。
accept="video/*" 可过滤出常见视频格式(mp4、webm、mov 等),但只是前端提示,不阻止伪造
file.type 和 file.name 后缀,比如 file.type.startsWith("video/")
webkitdirectory 或分片逻辑前的体积预检:if (file.size > 500 * 1024 * 1024) { alert("不能超过500MB"); return; }
FormData + fetch 发送视频到后端最稳妥别用 XMLHttpRequest 手动设 header——FormData 会自动处理 boundary,fetch 更简洁且默认兼容 multipart/form-data。
const fileInput = document.querySelector('input[type="file"]');
const uploadBtn = document.querySelector('#upload');
uploadBtn.addEventListener('click', async () => {
const file = fileInput.files[0];
if (!file) return;
const formData = new FormData();
formData.append('video', file); // 'video' 要和后端字段名一致
try {
const res = await fetch('/api/upload', {
method: 'POST',
body: formData // 不要设 Content-Type,让浏览器自动生成
});
const data = await res.json();
} catch (err) {
console.error('上传失败:', err);
}
});
Content-Type,否则 FormData 的 boundary 会被破坏,后端收不到文件video)必须和服务端解析逻辑匹配,比如 Express 用 multer.single('video')
fetch 的 upload.onprogress 需用 XMLHttpRequest,fetch 原生不支持上传进度90% 的“上传不了”问题不在 HTML 或 JS,而在服务端配置或网络拦截。
client_max_body_size 1024m;
body-parser,它不处理 multipart,必须换 multer 或 busboy
file:// 协议禁用 fetch 上传,务必用 http:// 或 https:// 测试Access-Control-Allow-Origin 和 Acce
ss-Control-Allow-Methods: POST,且不能用通配符 * 配合带凭证的请求iOS Safari 和部分安卓 WebView 上传相册视频时,file.type 经常是空字符串或 application/octet-stream,光靠 type 判断会失败。
file.name 后缀判断:const ext = file.name.split('.').pop().toLowerCase(); if (['mp4', 'mov', 'avi'].includes(ext)) { ... }
file.slice(0, 4).arrayBuffer()),比对 MP4 的 ftyp 或 MOV 的 moov 签名,但开销大,一般项目够用就行input type="file" 的调起行为有差异,建议加 capture="environment" 显式启用摄像头,避免相册混淆实际部署时最容易被忽略的是 Nginx 的 client_max_body_size 和后端 multipart 解析中间件是否真正生效——前端传得再对,后端卡在网关或解析层,日志里往往只报 400 或超时。