Nodejs отправляет файл в ответ


113

В платформе Expressjs есть метод sendfile (). Как я могу это сделать, не используя целый фреймворк. Я использую node-native-zip для создания архива и хочу отправить его пользователю.

Ответы:


184

Вот пример программы, которая отправит 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);

Взято с http://elegantcode.com/2011/04/06/taking-baby-steps-with-node-js-pumping-data-between-streams/


1
Но я не транслирую файл с сервера, я создаю архив
— андрей

Под «потоком» я подразумеваю «отправлять данные файла в соединение по мере его чтения», а не «читать весь файл в памяти, а затем сразу отправлять все эти данные в соединение» (что является типичным наивным подходом). Я не имею в виду «потоковую передачу данных из памяти без их записи на диск». Сообщение, на которое я ссылаюсь, объясняет более подробно.
— Мишель Тилли

6
util.pump (readStream, ответ); обесценивается ... используйте readStream.pipe (response);
— Афтершок

1
Это небезопасно. См .: stackoverflow.com/questions/20449055/node-js-stream-api-leak
— Kr0e

@Abdul Не уверен, что понимаю ваш вопрос; хочешь отправить мне электронное письмо ?
— Мишель Тилли,

13

Вам нужно использовать 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");
      }
    });
  }
}

Цель поля Content-Type - достаточно полно описать данные, содержащиеся в теле, чтобы принимающий пользовательский агент мог выбрать подходящий агент или механизм для представления данных пользователю или иным образом обработать данные соответствующим образом.

«application / octet-stream» определяется как «произвольные двоичные данные» в RFC 2046, цель этого типа содержимого - сохранить на диск - это то, что вам действительно нужно.

«filename = [имя файла]» указывает имя файла, который будет загружен.

Для получения дополнительной информации см. Этот раздел stackoverflow .


как запрос вызова на стороне клиента дает код на стороне клиента
— Ashwini

2
обратите внимание, что функция "существует" устарела.
— Евгений Наида
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.