Resumable.js无法将文件保存到服务器端目录

12

我正在使用Resumable.js与我的Node.js-express应用程序。我可以通过console.log(req.body)看到文件传输成功的情况...

{ resumableChunkNumber: '77',
  resumableChunkSize: '1048576',
  resumableCurrentChunkSize: '1064195',
  resumableTotalSize: '80755971',
  resumableType: '',
  resumableIdentifier: '80755971-humanfastq',
  resumableFilename: 'human.fastq',
  resumableRelativePath: 'human.fastq',
  resumableTotalChunks: '77' }

文档对于接下来要做什么相当模糊。 我需要将此文件保存到服务器上的目录中。 如果有任何关于如何完成此操作的帮助,将不胜感激。谢谢!


任何 Github 的示例都非常棒。 - Nodedeveloper101
好的,文件本身位于'req.files.file'...所以我有一个JavaScript变量是一个文件.. var file = req.files.file;....我该如何将此变量保存为文件到我的服务器上的特定目录? - Nodedeveloper101
我已经弄清楚了如何使用“fs”将.txt文件写入服务器。因此,我可以将文件写入服务器。我还可以使用console.log()记录有关文件的数据。但是我无法弄清楚必须传递到fs.writeFile(filename,file,callback)中的对象是什么,这实际上是文件...现在它只保存[object object]。 - Nodedeveloper101
2个回答

6

虽然我不是专家,但我试着为您做了一个示例。由于您在问题中没有提供足够的信息,因此我将从头开始。我遵循了官方GitHub仓库和提供的示例,但我必须进行一些调整,以便将文件块保存在特定目录中,然后再进行更多的调整来将这些块拼接在一起,并删除不必要的块。显然,所有这些调整都是代码中和我浏览的其他地方提供的提示。显然,flow.js也使用了类似的机制(不完全确定)。

我基本上需要更改一个示例中的app.js,以便能够从浏览器上传文件,然后将其保存到本地。

  1. 将目录位置传递给可恢复的位置,应将文件块添加到该位置
  2. 提供必要的条件和命令,以便在上传块时创建写入流,然后使用可恢复的位置将块拼接在一起并将其保存为原始文件。
  3. 最后删除所有块

使用gist中的说明使express-app工作(您可以查看官方GitHub示例并进行更改,或者您可以按照以下说明操作):

  1. 创建一个目录
  2. 在目录中使用gist创建app.js、resumable.js和resumable-node.js文件
  3. 复制/粘贴`package.json`并执行npm install命令以获取模块(或手动安装这些模块:`express`、`path`、`fs`、`connect-multiparty`)
  4. 在主应用程序目录中创建`uploads`目录,并确保它是可写的
  5. 此处复制`public`目录,其中包含.png格式的图标文件以及用于上传的`style.css`和`index.html`文件
  6. 将您服务器地址更改为`public`目录下刚刚复制的`index.html`文件中第49或50行的`target`值,例如我的地址是`http://localhost:3000/upload`
  7. 您可以在`index.html`中调整块大小、同时上传的块数等参数,但我将它们保留为默认值(实际上,我将块从3个增加到4个)
  8. 完成以上步骤后,您就可以开始使用了
  9. 运行应用程序即可,例如使用nodemon app.js或node app.js命令
  10. 转到您的服务器地址或http://localhost:3000/upload,您将看到如下所示的渲染后的`index.html`:

enter image description here

下面是控制台日志(请注意结尾处已删除的块):

enter image description here

最后,您将在`uploads`目录中找到保存的`image2.jpg`文件。

概括:

为了通过Resumable.js上传和保存已上传的文件,您需要对app.js和index.html文件进行以下调整。

更改`index.html`中的`target`值以指向服务器地址,例如我的地址是http://localhost:3000/upload

var r = new Resumable({
  target:'http://localhost:3000/upload',
  chunkSize:1*1024*1024,
  simultaneousUploads:4,
  testChunks:false,
  throttleProgressCallbacks:1
});

app.js 已经被修改,可以向 resumable 发送一个顶级目录来保存文件。

var resumable = require('./resumable-node.js')(__dirname + "/uploads");

我还修改了app.js以改变app.post('/uploads',...)的内容,请参见gist

// Handle uploads through Resumable.js
app.post('/upload', function(req, res){
  resumable.post(req, function(status, filename, original_filename, identifier){
    if (status === 'done') {
      var stream = fs.createWriteStream('./uploads/' + filename);

      //stich the chunks
      resumable.write(identifier, stream);
      stream.on('data', function(data){});
      stream.on('end', function(){});

      //delete chunks
      resumable.clean(identifier);
    }
    res.send(status, {
        // NOTE: Uncomment this funciton to enable cross-domain request.
        //'Access-Control-Allow-Origin': '*'
    });
  });
});

最后一次对app.js进行微调是在最后一个路由处理程序中,下面是相关文件。

s.createReadStream("./resumable.js").pipe(res);

我将resumable.js文件移动到与其他文件相同的目录中,因此我需要调整它的位置以便createReadStream找到它。


1
我没有使用Resumable.js,但是使用了类似的东西,以下是我在Nodejs/express服务器上的实现方式。您也可以在这里查看更多服务器代码:https://github.com/MichaelLeeHobbs/roboMiner/tree/master/server/api/world 但请注意,它并不完整且是实验性的。下面的代码仅为示例。
    import move from '../../libraries/fsMove.js';

    export function create(req, res) {
      var file = req.files.file;
      console.log(file.name);
      console.log(file.type);
      console.log(file.path);
      console.log(__dirname);
      move(file.path, __dirname + '/../../uploads/worlds/' + file.originalFilename, function(err){
        if (err) {
          console.log(err);
          handleError(res)(err);
          return;
        }
        World.createAsync(req.body)
          .then(responseWithResult(res, 201))
          .catch(handleError(res));
      });
    }

    // fsMove.js
    // https://dev59.com/F2oy5IYBdhLWcg3wZtNC#29105404
    var fs = require('fs');

    module.exports = function move (oldPath, newPath, callback) {
      fs.rename(oldPath, newPath, function (err) {
        if (err) {
          if (err.code === 'EXDEV') {
            copy();
          } else {
            callback(err);
          }
          return;
        }
        callback();
      });

      function copy () {
        var readStream = fs.createReadStream(oldPath);
        var writeStream = fs.createWriteStream(newPath);

        readStream.on('error', callback);
        writeStream.on('error', callback);
        readStream.on('close', function () {

          fs.unlink(oldPath, callback);
        });

        readStream.pipe(writeStream);

      }
    }; 

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