为什么在node.js中需要缓冲区?

4

使用Node在浏览器中显示文件内容,我首先尝试了以下方法:

var express = require('express')
  , fs  = require('fs')
  , app = express()
  , port = process.env.PORT || 5000;

app.use(express.logger());

var data = fs.readFileSync('index.html');


app.get('/', function(req, res){
  res.send(data);
});

app.listen(port, function(){
  console.log('Listenting on ' + port);
});

然而,这并没有像预期的那样起作用。实际上,浏览器提供了 index.html 的内容作为一个文件,我首先必须下载它,然后手动在文本编辑器中打开它。接着,我尝试使用缓冲区来做同样的事情:

var express = require('express')
  , fs  = require('fs')
  , app = express()
  , port = process.env.PORT || 5000;

app.use(express.logger());

var data = new Buffer(fs.readFileSync('index.html'));


app.get('/', function(req, res){
  res.send(data.toString('utf-8'));
});

app.listen(port, function(){
  console.log('Listenting on ' + port);
});

这段代码按预期工作,index.html的内容在浏览器窗口中显示。然而,在我有限的了解Node.js的情况下,Buffer类是处理二进制数据的全局类型。然而,index.html文件没有包含任何二进制数据。所以我的问题是:

  1. 在上述代码中,为什么index.html的内容被提供为文件下载(没有缓冲区),而不是直接在浏览器中显示(使用缓冲区)?
  2. 当文件只包含字符串数据而没有二进制数据时,为什么需要使用缓冲区?
  3. 缓冲区用于哪些其他场景?
  4. 如果我想了解更多关于缓冲区及其在Node中的使用,请问应该去哪里?

广告1)为了使文件能够被浏览器正确显示,您应该设置“Content-Type”头。 - Hubert OG
1个回答

3

正确的返回文件的方式是使用异步方法而不是同步方法。

 app.get('/', function(req, res){
   res.writeHead(200, {
    'Content-Type': 'text/plain' // set to whatever mime type you need. 
  });
  fileSystem.createReadStream(filePath).pipe(res);
});

如果你要用 express 来提供静态文件,那么你应该使用 static middleware 中间件。想要了解你的示例中的差异,请查看返回的 content-type ,这将决定浏览器对响应的处理方式。在第一种情况下,Express.js 会看到一个 Buffer,并决定将数据返回为 content-type "application/octet-stream" 的形式。你的浏览器不知道如何处理它并将其作为下载文件返回。而在第二种情况下,Express.js 会看到一个字符串,并决定将数据返回为 content-type "text/plain" 的形式。你的浏览器知道如何处理它并将其显示给你。我认为你的问题与 node.js 中的缓冲区关系不大,而更多地与 Express.js res.send 如何处理各种输入类型有关。如果你是 Node 的新手,我认为你不需要立即了解缓冲区。否则,请查看文档:http://nodejs.org/api/buffer.html#buffer_buffer

文件系统默认返回缓冲区而不是字符串,即使文件内容可能是纯字符串,我们需要设置HTTP内容类型头来覆盖此行为。有趣!感谢您的回复。 - CuriousMind
不,所有文件都是二进制的。我们只是根据文件类型以不同的方式解释这些字节。Buffer对象可以以不同的方式返回它所持有的字节,例如utf8字符串或base64。 - AndyD
正确的返回文件的方式是使用异步方法而不是同步方法。- 从内存中提供页面比异步磁盘读取要快得多,尽管如此,这个答案展示了一个读取流,而不是一个真正的异步方法。 - user1009387

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