Nodejs wysyła plik w odpowiedzi


113

Framework Expressjs ma metodę sendfile (). Jak mogę to zrobić bez używania całego frameworka. Do tworzenia archiwum używam node-native-zip i chcę wysłać to użytkownikowi.

Odpowiedzi:


183

Oto przykładowy program, który wyśle ​​plik myfile.mp3, przesyłając go strumieniowo z dysku (to znaczy nie wczytuje całego pliku do pamięci przed wysłaniem pliku). Serwer nasłuchuje na porcie 2000.

[Aktualizacja] Jak wspomniał @Aftershock w komentarzach, util.pumpzniknął i został zastąpiony metodą w prototypie Stream o nazwie pipe; poniższy kod to odzwierciedla.

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

Zaczerpnięte z http://elegantcode.com/2011/04/06/taking-baby-steps-with-node-js-pumping-data-between-streams/


1
Ale nie przesyłam strumieniowo pliku z serwera, tworzę archiwum
— andrei

Przez „strumień” mam na myśli „wysyłanie danych pliku do połączenia podczas ich odczytywania” w przeciwieństwie do „odczytywania całego pliku z pamięci, a następnie wysyłania wszystkich danych do połączenia naraz” (co jest typowym naiwnym podejściem). Nie mam na myśli „przesyłania strumieniowego danych z pamięci bez przechodzenia na dysk”. Post, do którego utworzyłem łącze, wyjaśnia bardziej szczegółowo.
— Michelle Tilley,

6
util.pump (readStream, odpowiedź); jest amortyzowany ... use readStream.pipe (odpowiedź);
— Aftershock


@Abdul Nie jestem pewien, czy rozumiem twoje pytanie; chcesz wysłać mi e-maila ?
— Michelle Tilley,

13

Aby wysłać plik (archiwum) w odpowiedzi, musisz użyć Stream, co więcej musisz użyć odpowiedniego typu treści w nagłówku odpowiedzi.

Oto przykładowa funkcja, która to robi:

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

Celem pola Content-Type jest opisanie danych zawartych w treści na tyle wyczerpująco, aby odbierający agent użytkownika mógł wybrać odpowiedniego agenta lub mechanizm do przedstawienia danych użytkownikowi lub w inny sposób poradzić sobie z danymi w odpowiedni sposób.

„strumień aplikacji / oktetu” jest definiowany jako „dowolne dane binarne” w RFC 2046, celem tego typu zawartości jest zapisanie na dysku - to jest to, czego naprawdę potrzebujesz.

„filename = [nazwa pliku]” określa nazwę pliku, który zostanie pobrany.

Aby uzyskać więcej informacji, zobacz ten temat dotyczący przepełnienia stosu .


jak żądanie połączenia po stronie klienta daje kod po stronie klienta
— ashwini

1
należy pamiętać, że funkcja „istnieje” jest przestarzała.
— Ievgen Naida
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.