2012-04-06 116 views
75

Expressjs框架有一個sendfile()方法。我怎麼做,而不使用整個框架。我正在使用node-native-zip創建一個存檔,並且我想將其發送給用戶。Nodejs發送文件作爲響應

回答

119

下面是一個示例程序,它將通過從磁盤流式傳輸myfile.mp3(即,在發送文件之前不會將整個文件讀入內存)。服務器監聽端口2000

[更新]作爲評價提及@Aftershock,util.pump消失,並與稱爲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/

+0

但我沒有從服務器上流式傳輸文件,我創建了存檔文件 – andrei 2012-04-06 21:32:25

+0

「流」我的意思是「發送文件數據到連接,因爲它正在讀取」,而不是「讀取內存中的整個文件,然後一次發送所有數據到連接「(這是典型的天真方法)。我並不是指「將內存中的數據流到磁盤中。」我鏈接的帖子更詳細地解釋了。 – 2012-04-06 22:57:45

+0

好吧,現在我明白了,謝謝。我會從那裏開始 – andrei 2012-04-08 08:56:39

3

您需要使用流以響應發送文件(檔案)拍攝的,更重要的是你有你的響應頭使用適當的內容類型。

有一個例子函數,做到這一點:

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字段的目的是描述包含在該人體完全足夠的是,接收用戶代理可以選擇一個合適的數據代理或機制向用戶呈現數據,或者以適當的方式處理數據。

「應用程序/八位字節流」在RFC 2046中定義爲「任意的二進制數據」,這種內容類型的目的是爲了保存到磁盤 - 什麼是你真正需要的。

「文件名= [文件名]」指定將被下載的文件的名稱。請參閱this stackoverflow topic