如何阻止 Express.js 重复长的多部分请求?

What to do to stop Express.js from duplicating long multipart requests?

考虑以下代码:

var routes = function(app) {
    app.post('/api/video', passport.authenticate('token', authentication), video.createVideo);
}

function createVideo(request, response) {
  logger.info('starting create video');
  upload(request, response, function(err) {
    logger.info('upload finished', err);
    //callback omitted for brevity
  }
}

使用 multer-s3 中间件上传 multer:

var upload = multer({
  storage: s3({
    dirname: config.apis.aws.dirname,
    bucket: config.apis.aws.bucket,
    secretAccessKey: config.apis.aws.secretAccessKey,
    accessKeyId: config.apis.aws.accessKeyId,
    region: config.apis.aws.region,
    filename: function(req, file, cb) {
      cb(null, req.user._id + '/' + uuid.v4() + path.extname(file.originalname));
    }
  }),
  limits: {
    fileSize: 1000000000
  },
  fileFilter: function(req, file, cb) {
    if (!_.contains(facebookAllowedTypes, path.extname(file.originalname))) {
      return cb(new Error('Only following types are allowed: ' + facebookAllowedTypes));
    }

    cb(null, true);
  }
}).fields([{
  name: 'video',
  maxCount: 1
}]);

上面的代码执行以下操作:它获取从某处发送的文件并将其流式传输到 AWS S3 实例。 multer-s3 在后台使用 s3fs 创建写入流并将文件作为 5MB 多部分发送。

上传大文件(例如 300MB)可能需要几分钟时间。现在发生了一些非常奇怪的事情。我可以在我们的前端看到它只在 /api/video 上发送一个 POST 请求。其实我也试过用Postman发出请求,不信任我们的前端。

它开始上传,但大约 2 分钟后它开始第二次上传!如果我尝试上传较小的文件,例如 2-100MB,那么什么都不会发生。这是来自我的日志(来自上面的代码):

{"name":"test-app","hostname":"zawarudo","pid":16953,"level":30,"msg":"starting create video","time":"2015-12-02T14:08:22.243Z","src":{"file":"/home/areinu/dev/projects/test-app-uploader/backend/app/services/videoService.js","line":169,"func":"createVideo"},"v":0}

{"name":"test-app","hostname":"zawarudo","pid":16953,"level":30,"msg":"starting create video","time":"2015-12-02T14:10:28.794Z","src":{"file":"/home/areinu/dev/projects/test-app-uploader/backend/app/services/videoService.js","line":169,"func":"createVideo"},"v":0}

{"name":"test-app","hostname":"zawarudo","pid":16953,"level":30,"msg":"upload finished undefined","time":"2015-12-02T14:12:46.433Z","src":{"file":"/home/areinu/dev/projects/test-app-uploader/backend/app/services/videoService.js","line":171},"v":0}

{"name":"test-app","hostname":"zawarudo","pid":16953,"level":30,"msg":"upload finished undefined","time":"2015-12-02T14:12:49.627Z","src":{"file":"/home/areinu/dev/projects/test-app-uploader/backend/app/services/videoService.js","line":171},"v":0}

如您所见,两次上传都在几毫秒后结束,但第二次上传在 2 分钟后开始。问题是 - 应该只有一个上传!

我在邮递员中所做的只是设置我的访问令牌(所以护照授权我)并添加了一个文件。这应该只创建 1 个上传,同时发生 2 个,并且都上传相同的文件。

此外,请注意两个文件都已上传,都有不同的 uuid(注意文件名函数从 uuid 创建文件名),都出现在 s3 上,并且都有 300MB 的适当大小,都可以下载并且都可以使用.

如果上传较小,则不会发生重复。这种行为的原因是什么?如何解决?

问题很简单(我只花了一整天就弄明白了)。这只是节点请求的默认超时 - 2 分钟。我不知道为什么它会启动另一个,也不知道它为什么能正常工作,但是将我服务器上的默认超时设置为 10 分钟解决了这个问题。

如果有人知道为什么超时请求确实完成了(并且两次),请告诉我。那我会改进答案的。