2012-04-06 17 views
75

Il framework Expressjs ha un metodo sendfile(). Come posso farlo senza usare un intero framework. Sto usando node-native-zip per creare un archivio e voglio inviarlo all'utente.Nodejs invia file in risposta

risposta

119

Ecco un programma di esempio che invierà myfile.mp3 eseguendolo in streaming dal disco (ovvero, non legge l'intero file in memoria prima di inviare il file). Il server in ascolto sulla porta 2000.

[Update] Come indicato da @Aftershock nei commenti, util.pump è andato ed è stato sostituito con un metodo sul prototipo torrente pipe; il codice qui sotto riflette questo.

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

Tratto da http://elegantcode.com/2011/04/06/taking-baby-steps-with-node-js-pumping-data-between-streams/

+0

Ma non sto trasmettendo un file dal server, creo l'archivio – andrei

+0

Per "flusso" intendo "inviare i dati del file alla connessione mentre viene letto" invece di "leggere l'intero file in memoria quindi invia tutti i dati alla connessione contemporaneamente "(che è il tipico approccio ingenuo). Non intendo dire "trasmetti i dati dalla memoria senza andare sul disco". Il post che ho collegato spiega in maggior dettaglio. –

+0

ok ora capisco, grazie. inizierò da lì – andrei

3

È necessario utilizzare Stream per inviare il file (filmati) in una risposta, ciò che è più devi usare appropriata Content-type nella vostra intestazione di risposta.

C'è una funzione di esempio che farlo:

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

Lo scopo del campo Content-Type è quello di descrivere i dati contenuti nel corpo abbastanza pienamente che l'agente utente ricevente può scegliere un adeguato agente o meccanismo per presentare i dati all'utente o altrimenti trattare i dati in modo appropriato.

"application/octet-stream" è definito come "dati binari arbitrari" in RFC 2046, scopo di questo tipo di contenuto deve essere salvato su disco - è ciò che è realmente necessario.

"nomefile = [nome del file]" specifica il nome del file che verrà scaricato.

Per ulteriori informazioni, vedere this stackoverflow topic.