Nodejs 发送文件作为响应

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10046039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 15:27:52  来源:igfitidea点击:

Nodejs send file in response

node.js

提问by andrei

Expressjs framework has a sendfile() method. How can I do that without using a whole framework. I am using node-native-zip to create an archive and I want to send that to the user.

Expressjs 框架有一个 sendfile() 方法。如果不使用整个框架,我怎么能做到这一点。我正在使用 node-native-zip 创建存档,我想将其发送给用户。

回答by Michelle Tilley

Here's an example program that will send myfile.mp3 by streaming it from disk (that is, it doesn't read the whole file into memory before sending the file). The server listens on port 2000.

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

[Update]As mentioned by @Aftershock in the comments, util.pumpis gone and was replaced with a method on the Stream prototype called pipe; the code below reflects this.

[更新]正如@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);

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

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

回答by MikePtr

You need use Stream to send file (archive) in a response, what is more you have to use appropriate Content-type in your response header.

您需要使用 Stream 在响应中发送文件(存档),更重要的是您必须在响应标头中使用适当的 Content-type。

There is an example function that do it:

有一个示例函数可以做到这一点:

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

The purpose of the Content-Type field is to describe the data contained in the body fully enough that the receiving user agent can pick an appropriate agent or mechanism to present the data to the user, or otherwise deal with the data in an appropriate manner.

Content-Type 字段的目的是充分描述包含在正文中的数据,以便接收用户代理可以选择合适的代理或机制将数据呈现给用户,或者以适当的方式处理数据。

"application/octet-stream" is defined as "arbitrary binary data" in RFC 2046, purpose of this content-type is to be saved to disk - it is what you really need.

“application/octet-stream”在 RFC 2046 中被定义为“任意二进制数据”,这种内容类型的目的是保存到磁盘 - 这是你真正需要的。

"filename=[name of file]" specifies name of file which will be downloaded.

“filename=[文件名]”指定要下载的文件名。

For more information please see this stackoverflow topic.

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