使用Node.js提供临时文件服务

13

我正在构建一个 NodeJs SOAP 客户端。起初,我设想服务器(即 Node SOAP 客户端)将通过 REST API(已进行身份验证)允许下载文档。经过一番在 Google 和 SO 上的搜索,看起来这是不可能的。

这意味着,当请求下载文档时,我必须为该文档进行 SOAP 调用,并通过 AJAX 返回一个 URL 给 REST 客户端。

为了做到这一点,我需要:

  1. 在 Node 中临时创建文件
  2. 获取其 URL 并返回给 Web 客户端
  3. 在发送响应时删除文件(出于安全目的)

以下是我的问题:

  1. 是否已经有一个框架可以做到这一点? temp 模块 可能是一个选项,但实际上我希望每个请求后都能删除,而不是在一段时间后删除。
  2. 如果没有,我能否只使用 NodeJs 文件系统和 Express 的 静态模块 来完成此操作?基本上我们将修改静态模块以使其看起来像这样:

    return function static(req, res, next) {
      if ('GET' != req.method && 'HEAD' != req.method) return next();
      var path = parse(req).pathname;
      var pause = utils.pause(req);
    
    /* My Added Code Here */
    res.on('end', function(){
        //  delete file based on req URL
    })
    /* end additions */
    
    function resume() {
      next();
      pause.resume();
    }
    
    function directory() {
      if (!redirect) return resume();
      var pathname = url.parse(req.originalUrl).pathname;
      res.statusCode = 301;
      res.setHeader('Location', pathname + '/');
      res.end('Redirecting to ' + utils.escape(pathname) + '/');
    }
    function error(err) {
       if (404 == err.status) return resume();
      next(err);
    }
    send(req, path)
      .maxage(options.maxAge || 0)
      .root(root)
      .hidden(options.hidden)
      .on('error', error)
      .on('directory', directory)
      .pipe(res);
    };
    

对于res.on('end',...这种写法是否有效?或者,我应该创建一些中间件来处理指向临时文件的URL?

2个回答

28

我找到了两个 Stack Overflow 的问题来回答我的问题。所以显然我们不需要使用 express.static 中间件。我们只需要使用文件系统来下载文件

app.get('/download', function(req, res){
 var file = __dirname + '/upload-folder/dramaticpenguin.MOV';
 res.download(file); // Set disposition and send it.
});

如果我们想要流式传输并删除,请按照以下步骤操作:stream and then delete

app.get('/download', function(req, res){
   var stream = fs.createReadStream('<filepath>/example.pdf', {bufferSize: 64 * 1024})
   stream.pipe(res);

   var had_error = false;
   stream.on('error', function(err){
      had_error = true;
   });
   stream.on('close', function(){
   if (!had_error) fs.unlink('<filepath>/example.pdf');
});

非常棒,你帮我省了很多时间,我自己本来要去弄明白这个问题。给你点赞,先生。 - Cory Gross
牛逼的解决方案!我已经搜索了几天,很高兴找到了这个。+1!! - Neurax

12

如果您在2015年12月之后访问此SO页面,则可能发现先前的解决方案不起作用(至少对我来说不起作用)。我找到了另一种解决方案,因此我想在这里为未来的读者提供它。

app.get('/download', function(req, res){
    res.download(pathToFile, 'fileNameForEndUser.pdf', function(err) {
        if (!err) {
            fs.unlink(path);
        }
    });
});

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