Зачем нужны буферы в node.js?

Чтобы отобразить содержимое файла в браузере с помощью узла, я сначала попробовал это:

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. Класс буфера — это глобальный тип для работы с двоичными данными. Однако файл index.html не содержал двоичных данных. поэтому мои вопросы:

  1. Почему в приведенном выше коде содержимое index.html предлагалось как загрузка файла (без буфера), а не отображалось непосредственно в браузере (с буфером)?
  2. Зачем мне использовать буфер, когда файл содержит только строковые данные, а не двоичные?
  3. Каковы места предложения, где используются буферы?
  4. Если я хочу узнать больше о буферах и их использовании в Node. куда я иду?

person CuriousMind    schedule 14.07.2013    source источник
comment
Объявление 1) Вы должны установить заголовок Content-Type, чтобы файл правильно отображался в браузере.   -  person Hubert OG    schedule 14.07.2013


Ответы (1)


Правильный способ вернуть файл — использовать асинхронный метод вместо метода синхронизации:

 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, вам следует использовать статическое промежуточное ПО.

Чтобы узнать различия в вашем примере, посмотрите на возвращаемый тип контента. Это то, что будет определять, что браузер делает с вашим ответом.

В первом случае Express.js увидел бы буфер и решил вернуть данные как тип содержимого «application/octet-stream». Ваш браузер не будет знать, что с этим делать, и вернет его в виде загружаемого файла.

Во втором случае Express.js увидел бы строку и решил вернуть данные как тип содержимого «текст/обычный». Ваш браузер знает, как с этим справиться, и покажет вам это.

Я не думаю, что ваш вопрос имеет много общего с буферами в node.js, но больше связан с тем, как Express.js res.send обрабатывает различные типы ввода.

Если вы новичок в Node, я думаю, вам не нужно сразу знать о буферах. В противном случае взгляните на документы: http://nodejs.org/api/buffer.html#buffer_buffer

person AndyD    schedule 14.07.2013
comment
Таким образом, файловая система по умолчанию возвращает буферы, а не строки, даже если содержимое файла может быть чистыми строками, и нам нужен заголовок типа содержимого HTTP, чтобы переопределить это. Интересно! Спасибо за ответ. - person CuriousMind; 14.07.2013
comment
Нет. Все файлы всегда бинарные. Мы просто интерпретируем эти байты по-разному в зависимости от типа файла. Объект Buffer может возвращать содержащиеся в нем байты различными способами, например, в виде строки utf8 или base64. - person AndyD; 14.07.2013
comment
The correct way to return a file would be to use an async method instead of a sync method.: - ну, обслуживание страницы из памяти, возможно, намного быстрее, чем асинхронное чтение с диска. Тем не менее, этот ответ показывает поток чтения, а не асинхронный метод как таковой. - person Thomas Foster; 02.04.2015