Nodejs发送文件作为响应

and*_*rei 103 node.js

Expressjs框架有一个sendfile()方法.如果不使用整个框架,我该怎么做呢?我使用node-native-zip创建存档,我想将其发送给用户.

Mic*_*ley 162

这是一个示例程序,它将通过从磁盘流式传输myfile.mp3(也就是说,它不会在发送文件之前将整个文件读入内存).服务器侦听端口2000.

[更新]正如@Aftershock在评论中提到的那样,util.pump已经不见了,并被Stream原型上的一个方法所取代pipe; 下面的代码反映了这一点.

var http = require('http'),
    fileSystem = require('fs'),
    path = require('path');

http.createServer(function(request, response) {
    var filePath = path.join(__dirname, 'myfile.mp3');
    var stat = fileSystem.statSync(filePath);

    response.writeHead(200, {
        'Content-Type': 'audio/mpeg',
        'Content-Length': stat.size
    });

    var readStream = fileSystem.createReadStream(filePath);
    // We replaced all the event handlers with a simple call to readStream.pipe()
    readStream.pipe(response);
})
.listen(2000);
Run Code Online (Sandbox Code Playgroud)

取自http://elegantcode.com/2011/04/06/taking-baby-steps-with-node-js-pumping-data-between-streams/

  • util.pump(readStream,response); 折旧...使用readStream.pipe(响应); (6认同)
  • 这不安全。请参阅:http://stackoverflow.com/questions/20449055/node-js-stream-api-leak (2认同)

Mik*_*Ptr 10

您需要使用Stream在响应中发送文件(存档),您还需要在响应头中使用适当的Content-type.

有一个示例函数可以执行此操作:

const fs = require('fs');

// Where fileName is name of the file and response is Node.js Reponse. 
responseFile = (fileName, response) => {
  const filePath =  "/path/to/archive.rar" // or any file format

  // Check if file specified by the filePath exists 
  fs.exists(filePath, function(exists){
      if (exists) {     
        // Content-type is very interesting part that guarantee that
        // Web browser will handle response in an appropriate manner.
        response.writeHead(200, {
          "Content-Type": "application/octet-stream",
          "Content-Disposition": "attachment; filename=" + fileName
        });
        fs.createReadStream(filePath).pipe(response);
      } else {
        response.writeHead(400, {"Content-Type": "text/plain"});
        response.end("ERROR File does not exist");
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

Content-Type字段的目的是完全描述主体中包含的数据,使得接收用户代理可以选择适当的代理或机制来向用户呈现数据,或者以适当的方式处理数据.

RFC 2046中将"application/octet-stream"定义为"任意二进制数据",此内容类型的目的是保存到磁盘 - 这是您真正需要的.

"filename = [文件名]"指定将下载的文件名.

有关更多信息,请参阅此stackoverflow主题.

  • 请注意,“exists”函数已被弃用。 (3认同)

Deb*_*obi 5

这对我有帮助。一旦您到达路线,它就会开始下载文件/your-route

app.get("/your-route", (req, res) => {

         let filePath = path.join(__dirname, "youe-file.whatever");

         res.download(filePath);
}
Run Code Online (Sandbox Code Playgroud)

是的download也是一种表达方法。