如何跟踪文件上传到 NodeJs 服务器的进度。我在服务器端使用 multer 上传文件。 ?
我是否需要向客户端发送某种信息,以便客户端获取上传进度,或者这是在内部完成的,客户端可以在其上跟踪进度。
下面是我用来上传文件的代码:
var multer = require('multer');
app.use(multer({dest:'./tmp',limits: {fileSize: 4*1024*1024}}).single('upload'));
router.post('/upload',function(req,res){
console.log(req.file);
});
最佳答案
Multer 在跟踪文件上传进度方面不是很灵活。 我尝试了很多方法,使用 progress-stream 库来传输请求,制作我自己的函数来计算百分比,然后将进度流式传输到 socket.io,以及其他东西。 socket.io 的方法(将百分比流式传输到套接字,返回客户端)在一定程度上起作用,但主要问题是 Multer 在文件上传到服务器之前不会返回执行控制, 所以如果你把它设置成一个中间件函数,比如:
this.router.post('/upload', upload.single('file'), function(req: Request, res: Response) {...}
你不可能获得进度或 req.file(如果你尝试在 upload.single 之前添加一个中间件,比如 this.router.post('/upload', dosomething, upload.single('file' )...),因为那时 req.file 将不存在,之后一旦您尝试访问 req.file 它将是 100%。这就是中间件的工作方式。 如果您需要跟踪进度,但不将其发送回客户端(如果您需要进度条则不是这种情况),那么您可以像我下面那样做。 但!这将起作用,因为您将计算请求大小,而不是 req.file 大小(req.file 仅存在于 Multer 的上下文中) 并不是说它有很大的不同,req 和 req.file 来自同一个请求,所以如果你使用下面的代码,你将看到百分比,然后将运行使用 Multer 保存文件的代码。 跟踪服务器大小进度的示例是:
var uploadImages = multer({ dest: ...}).single('...');
//more code ...
this.router.post('/upload', (req: Request, res: Response) => {
let progress = 0;
let fileSize = req.headers['content-length'] ? parseInt(req.headers['content-length']) : 0;
req.on('data', (chunk) => {
progress += chunk.length;
res.write((`${Math.floor((progress * 100) / fileSize)} `));
if (progress === fileSize) {
console.log('Finished', progress, fileSize)
}
});
})
//And calling the Multer function down here...
uploadImages(req,res...){}
调用中间件函数以使用 Multer 上传文件,而不是在路由声明中使用它,在 Multer 的文档中指定(其中显示“错误处理”)。 “如果你想专门从 Multer 中捕获错误,你可以自己调用中间件函数。”
req.file 的值只会存在于数据到达 Multer 进行处理和保存的上下文中。 所以我建议,对于任何试图想出一种方法的人,如果可以的话,你可以在服务器端监听进度,并且需要在前端做,你可以使用 Axios,它有一个非常好的 Hook 以跟踪进度,以实现 promise 。
发送表单数据并跟踪进度的示例:
saveFile(file,url): Promise<...> {
let formData = new FormData();
formData.append('file', file);
const config = {
onUploadProgress: (progressEvent) => {
var percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total)
//do something with the percentCompleted
//I used an observable to pass the data to a component and subscribed to it, to fill the progressbar
}
}
return axios.post(url, formData, config)
}
希望它能满足您的需求,并帮助您避免头痛。
关于node.js - 在 multer nodejs 中跟踪文件上传的进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35288625/