如何在jquery.fileupload中设置单文件及总上传文件大小限制?
解决文件上传大小提前校验的问题
刚好碰到过类似的场景,给你一套前后端结合的方案,既能让用户立刻收到大小超限的提示,又能避免后端等文件传完才报错的尴尬,还能补上multiparty做不了的单文件大小限制。
前端即时校验(给用户快速反馈)
既然用的是jquery.fileupload,它自带的add事件可以在文件刚被选中、还没开始上传时就做校验,完全不用等上传请求发出去。你可以在这里同时检查单个文件大小和总文件大小:
$('#fileupload').fileupload({ url: '/your-upload-endpoint', add: function(e, data) { // 先定义好限制值,单位是字节,这里设10MB单文件、50MB总大小 const singleFileLimit = 10 * 1024 * 1024; const totalFileLimit = 50 * 1024 * 1024; let totalSize = 0; let isInvalid = false; // 逐个检查单文件大小 data.files.forEach(file => { totalSize += file.size; if (file.size > singleFileLimit) { alert(`文件 ${file.name} 太大啦,单文件最多10MB哦`); isInvalid = true; } }); // 检查总大小 if (!isInvalid && totalSize > totalFileLimit) { alert(`选的文件总大小超过50MB啦,删减一些再试试吧`); isInvalid = true; } // 只有全部校验通过才提交上传 if (!isInvalid) { data.submit(); } } });
不过要注意:前端校验只是给用户方便,不能完全依赖——懂技术的用户可以绕过前端限制直接发请求,所以后端必须兜底校验。
后端实时拦截(安全兜底+提前报错)
multiparty默认的总大小限制确实要等传够数据才触发,那我们换个思路:在接收文件的过程中实时计算大小,一旦超过限制就立刻终止请求,不用等文件传完。
具体实现步骤:
- 监听multiparty的
part事件(每个上传的文件对应一个part) - 在
data事件里实时累加当前文件的大小和总上传大小 - 只要任一限制被触发,立刻返回错误响应并终止表单解析
代码示例:
const multiparty = require('multiparty'); const http = require('http'); http.createServer((req, res) => { if (req.url === '/your-upload-endpoint' && req.method === 'POST') { const singleFileLimit = 10 * 1024 * 1024; // 10MB const totalFileLimit = 50 * 1024 * 1024; // 50MB let totalUploaded = 0; let hasError = false; const form = new multiparty.Form(); // 监听每个文件块的接收 form.on('part', (part) => { // 如果已经报错,直接跳过当前文件的接收 if (hasError) { part.resume(); return; } let currentFileSize = 0; part.on('data', (chunk) => { currentFileSize += chunk.length; totalUploaded += chunk.length; // 检查单文件大小 if (currentFileSize > singleFileLimit) { hasError = true; res.writeHead(400, {'Content-Type': 'text/plain'}); res.end(`文件 ${part.filename} 超过单文件大小限制(最大10MB)`); // 手动触发错误终止表单解析 form.emit('error', new Error('Single file size exceeded')); part.resume(); // 释放资源,避免内存泄漏 } // 检查总大小 else if (totalUploaded > totalFileLimit) { hasError = true; res.writeHead(400, {'Content-Type': 'text/plain'}); res.end('所有文件总大小超过限制(最大50MB)'); form.emit('error', new Error('Total file size exceeded')); part.resume(); } }); part.on('end', () => { // 这里可以处理合法文件的保存逻辑,前提是没有报错 if (!hasError) { // 比如把文件写入磁盘或者存到云存储 // fs.writeFileSync(`./uploads/${part.filename}`, ...); } }); }); // 处理错误,防止请求挂起 form.on('error', (err) => { req.destroy(); }); form.parse(req); } else { // 这里返回上传页面,方便测试 res.writeHead(200, {'Content-Type': 'text/html'}); res.end('<form action="/your-upload-endpoint" method="post" enctype="multipart/form-data"><input type="file" multiple><button type="submit">上传文件</button></form>'); } }).listen(3000);
这样一来,只要文件大小超过限制,后端会立刻切断连接并返回错误,用户不用等半天才能收到提示,而且单文件和总大小的限制都能实现。
另外,如果之后有重构的需求,也可以考虑换成multer这个库——它本身内置了单文件和总文件的大小限制,配置起来更简单,而且能更早触发错误拦截,不过如果不想换现有技术栈,上面的multiparty方案完全够用。
内容的提问来源于stack exchange,提问作者rpd
相关产品推荐
相关产品推荐

