Nodejs надсилає файл у відповідь


113

Expressjs Framework має метод sendfile (). Як я можу це зробити, не використовуючи цілий фреймворк. Я використовую node-native-zip для створення архіву, і я хочу надіслати це користувачеві.

Відповіді:


183

Ось приклад програми, яка надішле файл 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
Але я не передаю файл з сервера, я створю архів
— andrei

Під "потоком" я маю на увазі "надіслати файлові дані до з'єднання під час його зчитування", на відміну від "прочитати весь файл у пам'яті, а потім надіслати всі ці дані відразу до з'єднання" (що є типовим наївним підходом). Я не маю на увазі "передавати дані з пам'яті, не переходячи на диск". Пост, з яким я пов’язаний, пояснюється більш докладно.
— Мішель Тіллі

6
util.pump (readStream, відповідь); амортизується ... використовувати readStream.pipe (відповідь);
— Aftershock


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

13

Для надсилання файлу (архіву) у відповіді вам потрібно використовувати Потік. Більше того, вам потрібно використовувати відповідний тип вмісту у своєму заголовку відповіді.

Є приклад функції, яка виконує це:

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 = [ім'я файлу]" вказує ім'я файлу, який буде завантажено.

Для отримання додаткової інформації дивіться цю статтю .


як запит виклику на стороні клієнта надає код сторони клієнта
— ashwini

1
зверніть увагу, що функція "існує" застаріла.
— Євген Найда
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.