Sails.js实现同一文件上传至两个路径的问题排查
问题分析与解决方案
首先,你遇到的核心问题是:Sails.js的req.file().upload()方法在处理完一次上传后,会消耗掉请求中的文件流,第二次调用时已经没有文件数据可以读取了。这就是为什么你只看到文件被传到第一个路径,第二次上传实际没有生效,控制台输出的路径大概率是第一次上传的缓存或错误复用的信息。
另外你的代码还有几个需要先修正的小问题:
var imgPathArr;未初始化就调用push,会触发ReferenceError,应该改成var imgPathArr = [];res.send("ok");放在了第二个上传回调的外面,会导致响应提前发送,第二个上传操作可能还没完成就结束了请求。
正确实现思路
要实现同一文件上传到多个路径,最稳妥的方式是:
- 先将文件上传到其中一个目标路径(或者临时目录)
- 然后用Node.js的
fs模块将已上传的文件复制到另一个路径
修正后的代码示例
var imgPathArr = []; // 初始化数组 var dePathWeb = 'd:/images/web'; var dePathMobile = 'd:/images/mobile'; imgPathArr.push(dePathWeb); imgPathArr.push(dePathMobile); const fs = require('fs'); const path = require('path'); req.file('file').upload({ dirname: path.resolve(imgPathArr[0]) }, function (err, uploadedFiles) { if (err) return res.send(500, err); if (uploadedFiles.length === 0) { return res.send(400, 'No file uploaded'); } const sourceFilePath = uploadedFiles[0].fd; const targetFilePath = path.join(imgPathArr[1], path.basename(sourceFilePath)); // 复制文件到第二个路径 fs.copyFile(sourceFilePath, targetFilePath, (copyErr) => { if (copyErr) { console.error('Failed to copy file:', copyErr); return res.send(500, 'Failed to copy file to mobile directory'); } console.log("uploadedFiles web " + sourceFilePath); console.log("files mobile " + targetFilePath); res.send("ok"); }); });
为什么这个方案可行?
- 第一次上传完成后,我们已经有了本地的文件副本,直接通过文件系统复制比重新处理上传请求更高效
- 彻底避免了重复消耗请求文件流的问题
- 确保两个操作都完成后才发送响应给客户端
如果你更倾向于现代Node.js的Promise风格写法,可以用fs.promises.copyFile:
var imgPathArr = []; var dePathWeb = 'd:/images/web'; var dePathMobile = 'd:/images/mobile'; imgPathArr.push(dePathWeb); imgPathArr.push(dePathMobile); const fs = require('fs').promises; const path = require('path'); req.file('file').upload({ dirname: path.resolve(imgPathArr[0]) }, async function (err, uploadedFiles) { if (err) return res.send(500, err); if (uploadedFiles.length === 0) { return res.send(400, 'No file uploaded'); } const sourceFilePath = uploadedFiles[0].fd; const targetFilePath = path.join(imgPathArr[1], path.basename(sourceFilePath)); try { await fs.copyFile(sourceFilePath, targetFilePath); console.log("uploadedFiles web " + sourceFilePath); console.log("files mobile " + targetFilePath); res.send("ok"); } catch (copyErr) { console.error('Failed to copy file:', copyErr); res.send(500, 'Failed to copy file to mobile directory'); } });
内容的提问来源于stack exchange,提问作者Dilakshan Sooriyanathan
相关产品推荐
相关产品推荐

