将大文件上传到NodeJS Web服务器

11
我目前使用 NodeJS 服务器(ExpressJS)提供我的 Web 应用程序。新需求之一是允许用户将大型视频文件(可能达到几个 GB)上传到服务器,然后再下载它们。我能否在当前技术栈下实现这一点?
我发现了一些教程,使用 Multer JS 并在前端指定 "multipart/form-data"。如果我使用它,我的 Express 能否在将巨大的单个视频文件写入服务器磁盘时继续处理其他 HTTP 请求?
3个回答

5

我自己曾经处理过这个问题(没有使用multer,文件大小约为20GB),我可以推荐以下步骤(可能你已经考虑到了其中的大部分,但为了完整起见):

  1. 选择合适的上传控件(或编写自己的上传控件,但基本上最好是将数据分块。我使用了plupload)

  2. 在服务器上创建一个API来处理收到的块数据,并在上传过程中将其写入临时位置(您可能还想对单个块进行哈希和检查)。

  3. 上传完成后,检查文件(我使用客户端生成的哈希值,并将其与上传的数据进行比较)。


只是好奇,您决定不使用 multer 的原因是什么? - Randy
2
我是在4/5年前做的...都不认为这个项目存在(当时我们还在用很多Flash来进行HTML5的兼容处理 :O) - major-mann

4

Multer应该可以很好地工作。它会将数据作为HTTP传输到磁盘上的文件中。它不会锁定您的服务器。然后在您的端点中,您可以访问该文件位置并对其进行必要的处理。


3
顺便提一下:那么您是直接将该文件上传到 S3 吗?如果是的话,您实际上可以让客户端直接将文件上传到 S3。这将节省您的 Node 服务器处理几 GB 数据的时间。而且,S3 可能会比您自己的服务器更快地将文件返回给用户。 - Randy
上传到S3似乎是一个不错的解决方案。既然你推荐它,我猜在安全方面这样做是安全的吧?毕竟你肯定不希望任何人开始上传文件到你的S3,所以是否有某种身份验证方案? - jiminssy
1
客户向您的API请求S3访问令牌。您的API基本上使用亚马逊提供的S3库创建此令牌。这是一个临时令牌,您的客户将使用它连接到S3以上传文件。上传完成后,您可以使用路径或标识符回调到您的API。然后,您的API可以随意使用S3文件。 - Randy
1
有一个 multer s3 插件 https://github.com/badunk/multer-s3/ 或许会很有用。 - Hosar
5
我正在使用 multer,但它总是首先将文件加载到内存中,而不是将数据流式传输到磁盘上,有任何想法吗? - pagep
显示剩余3条评论

0
    var express =   require("express");

    var app =   express();
    var async = require('async');
    var fs = require('fs');
    var client = redis.createClient();
    var multiparty = require('multiparty');
    var util = require('util');

    app.post('/',function(req,res){

        var form = new multiparty.Form();

        form.parse(req, function(err, fields, files) {

             client.get(fields.otp, function(err, reply) {
    var oldpath = files.file[0].path;
                          var newpath = path + files.file[0].originalFilename;
                          fs.rename(oldpath, newpath, function (err) {
                            if (err) throw err;
                            res.write('File uploaded and moved!');
                            res.end();
                          });
    }
    }



app.listen(2001,function(){
    console.log("Server is running on port 2001");
});

我很感激你的代码,但是我不清楚multipartymulter有什么区别。而且,你使用redis客户端的原因也完全不清楚。在multiparty示例中没有客户端。提示:添加注释以使这些内容对他人有帮助和清晰。为什么这个建议比上面的答案更好(或相等)? - zipzit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接