【问题标题】:How to use the stop event on server side when all files are uploaded in jQuery File Upload在jQuery File Upload中上传所有文件时如何在服务器端使用停止事件
【发布时间】:2016-11-20 00:43:18
【问题描述】:

我在 express.js 上使用 jQuery File Upload 和 jquery-file-upload-middleware 和 mongoose 和 mongoDB。

我想上传画廊的图片。 Galery对象包含一个Image对象数组,如

var GalerySchema = new mongoose.Schema({
    images: [ImageSchema]
})

每个文件异步上传后,我想将其推送到我的 Galery 对象的 images 数组中。

我尝试做以下服务器端:

// Is called everytime an image is uploaded
upload.on('end', function(fileInfo, rew, res){
    // Get the galery
    db.Galery.findOne({_id: req.fields.galery_id}, function(err, galery){

        // Create new Image object instance
        var image = new db.Image({src: fileInfo.name});

        // Save, in order to create auto generated _id
        image.save(function(err){
            if(err) {console.log(err); return; }

            // Add to Images array of Galery object
            galery.images.push(image);

            // Save galery with added image
            galery.save(function(err){
                if(err) { console.log(err); return; }
            });
        })
    });
});

这样做,我得到了一个众所周知的[VersionError: No matching document found.],据我目前所知,这是由于同时访问同一个 mongodb 文档,因为上传是异步进行的。

所以为了处理异步方式的问题,最好等待所有上传完成,然后使用async.parallel()将图像一一插入到mongodb中。

但是如何访问所有上传已完成的事件?

我知道浏览器端我可以使用stop event。但首先这不包含有关上传文件的任何数据。另外,我想在服务器端做。

有没有类似的东西

upload.on('doneAll', function(allFilesInfo, req, res){...})?

【问题讨论】:

  • 你试过用res吗? res.end('Uploaded')
  • 我刚刚通过在 jQuery 文件上传属性中设置 sequentialUploads: true 找到了一种解决方法,以便一个接一个地上传。不过,我真的很想知道如何异步进行。
  • 我不确定您使用哪个库来获取上传的图像。您需要知道最后一张图片的 upload.on('end' 何时被调用。有什么办法知道吗?
  • 是的,但我不知道如何获取此事件。如问题中所述,我使用的库是 jquery-file-upload-middleware。它基于 jQuery 文件上传。
  • 如果每个上传的请求是分开的和独立的,逻辑上服务器将不知道(也不应该)是否有更多文件。更好的解决方案是让您的客户端在上传完成后执行 ajax/socket 调用,然后这会触发一个服务器路由,该路由在服务器上执行您想要的操作。

标签: jquery node.js mongodb file-upload jquery-file-upload


【解决方案1】:

在上传时,如果您使用sequentialUploads: true,则每个文件都向服务器发出一个请求,或者总共发出一个请求。如果您想知道所有图像何时在异步场景中上传,您需要使用 express 定义一个额外的路由,并在调用此路由的所有文件完成时向 fileuploader 添加一个回调。然后,您还需要跟踪哪些文件已上传但之前未保存。如果您的脚本被多人使用(公共访问?),那么您还需要实现一些会话处理以保存在调用“uploadDone”路由时要添加的上传文件。如您所见,这是很多开销,所以我建议使用sequentialUploads: true 解决方案。

但我几乎不相信您会得到[VersionError: No matching document found.],因为同时访问图库文档,因为获取/保存文档只需几毫秒。我建议您检查是否发送了req.fields.galery_id

console.log(req.fields.galery_id);

【讨论】:

    【解决方案2】:

    由于 jQuery File Upload 为每个文件创建一个 XHR,这些在服务器端被视为单独的 POST,并且上传中间件无法直接知道所有上传何时完成。您可以创建另一个端点来作为停止事件的回调,但这不仅缺少有关上传内容的信息,正如您已经知道的那样,而且如果两个或更多用户碰巧正在上传,也无济于事同时。

    我相信您需要调用findOneAndUpdate(或findByIdAndUpdate)来对Galery 执行更新。请参阅此answer,了解如何将$pushimage 转换为galery 的示例。

    【讨论】:

      【解决方案3】:

      你可以使用 Promise(Bluebird:https://github.com/petkaantonov/bluebirdnpm install bluebird --save)并有这样的东西:

      var BPromise = require('bluebird');
      
      var uploadDone = new BPromise(function (resolve, reject) {
      
          // your image upload
      
      });
      
      uploadDone.then(function (result) {
      
         // upload complete here
      
      }, function (error) {
         console.log("Error: ", error);
      });
      

      【讨论】:

      • 这并没有解决 when 解决承诺的问题,这或多或少是 OP 想知道的。
      猜你喜欢
      • 1970-01-01
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      相关资源
      最近更新 更多