node.js - 在 multer nodejs 中跟踪文件上传的进度

标签 node.js http npm multer

如何跟踪文件上传到 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/

相关文章:

javascript - 重复将 PNG 发送到服务器。我想告诉传入的浏览器在计时器上刷新

http - 超时与服务器无响应,我如何区分它们?

google-chrome - NaCl 辅助进程在没有沙箱的情况下运行!运行 npm 测试时出错

node.js - 上传 PDF 文件到 Express 服务器

javascript - Express JS 中的路由参数

Node.js:追加到文件而不关闭句柄

java - 关闭在 HttpRequestHandler 的句柄中创建的套接字

javascript - Babel Compile 停止命令链

node.js - 关于 npm install 和 npm update 的困惑

javascript - 我应该避免异步处理 Promise 拒绝吗?