更新:
感謝@ jfriend00的建議,這是更好,更有效地直接發送緩衝區,以客戶爲文件,而不是在服務器磁盤先保存它。
實現,stream.PassThrough()
,可用於pipe()
,這裏有一個例子:
var stream = require('stream');
//...
app.get('/download', function(request, response){
//...
var fileContents = Buffer.from(fileData, "base64");
var readStream = new stream.PassThrough();
readStream.end(fileContents);
response.set('Content-disposition', 'attachment; filename=' + fileName);
response.set('Content-Type', 'text/plain');
readStream.pipe(res);
});
根據快遞document,res.download()
API是:
res.download(路徑[,文件名] [,fn])
將路徑中的文件作爲「附件」傳輸。通常,瀏覽器會提示用戶下載。默認情況下,Content-Disposition頭文件「filename =」參數是路徑(通常出現在瀏覽器對話框中)。用filename參數覆蓋這個默認值。
請注意res.download()
的第一個參數是一個「路徑」,它表示將要下載的服務器中的文件路徑。在你的代碼中,第一個參數是一個Buffer,這就是爲什麼Node.js會抱怨「filename參數必須是一個字符串」 - 默認情況下,Content-Disposition
頭文件「filename =」參數是路徑。
要使用res.download()
你的代碼工作,你需要在fileData
服務器保存爲一個文件,然後調用res.download()
與該文件的路徑:
var fs = require('fs');
//...
app.get('/download', function(request, response){
//...
var fileContents = Buffer.from(fileData, "base64");
var savedFilePath = '/temp/' + fileName; // in some convenient temporary file folder
fs.writeFile(savedFilePath, fileContents, function() {
response.status(200).download(savedFilePath, fileName);
});
});
另外,請注意new Buffer(string[, encoding])
現在已經過時了。最好使用Buffer.from(string[, encoding])
。
哪一行給出錯誤? –
請用'let'聲明你的局部變量,如'fileType','fileName'和'fileData'。在服務器中使用偶然的全局變量是一種災難。 – jfriend00
如果你看[res.download()']代碼(https://github.com/expressjs/express/blob/master/lib/response.js#L514),你可以看到它只是調用'res.sendFile()'所以它只能用來從文件中發送數據,而不是從內存中發送數據。您將不得不尋找一種不同的方式直接從內存發送或首先寫入臨時文件。 – jfriend00