Serving Temporary Files with NodeJs

2020-05-23 09:13发布

I am building a NodeJs SOAP client. Originally, I imagined the server (ie the node SOAP client) would allow downloading documents through a REST API (the REST API is authenticated). After a good deal of time on Google and SO, looks like that is not possible.

That means when a document download is requested, I'll have to make a SOAP call for the document and return a URL to the REST client via AJAX.

In order to do this I'll need to:

  1. Temporarily create a file in Node
  2. get its URL and return to web client
  3. When the file is requested and response is sent, delete the file (for security purposes)

Here are my questions:

  1. Is there already a framework that does this? the temp module might be an option, but really I'd like to delete after every request, not after a time period.
  2. If not, can I do this just using the NodeJs File System, and Express static module? Basically we would modify the static module to look like this:

    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);
    };
    

Is res.on('end',... vaild? Alternatively,should I create some middleware that does this for URLs pointing to the temporary files?

2条回答
Root(大扎)
2楼-- · 2020-05-23 09:30

Found two SO questions that answer my question. So apparently we don't need to use the express.static middleware. We just need the filesystem to download a file:

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

If we want to stream and then delete follow:

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');
});
查看更多
Animai°情兽
3楼-- · 2020-05-23 09:45

If you are visiting this SO page after Dec 2015, you may find that the previous solution isn't working (At least it isn't working for me). I found a different solution so I thought I would provide it here for future readers.

app.get('/download', function(req, res){
    res.download(pathToFile, 'fileNameForEndUser.pdf', function(err) {
        if (!err) {
            fs.unlink(path);
        }
    });
});
查看更多
登录 后发表回答