如何给node.js express应用程序中的用户提供下载窗口选项

我正在构build一个node.js + express应用程序。 一个Excel文件被创build在我的服务器端,我需要在下载窗口中将其提供给用户。 所以用户可以select他想要的目录然后下载它。 用户完成后,我想要删除该文件(在应用程序的本地下载文件夹中创build)。

这是我的代码:

router.post('/filter', function(req, res){ try { var root = path.dirname(require.main.filename); var downloadsDir = root + '/downloads'; var workbook = new Excel.Workbook(); var worksheet = workbook.addWorksheet('My Sheet'); worksheet.columns = [ { header: 'Id', key: 'id', width: 10 }, { header: 'Name', key: 'name', width: 32 }, { header: 'DOB', key: 'DOB', width: 10 } ]; worksheet.addRow({id: 1, name: 'John Doe', dob: new Date(1970,1,1)}); worksheet.addRow({id: 2, name: 'Jane Doe', dob: new Date(1965,1,7)}); //ensure a download directory exist, if not then create it fs.ensureDir(downloadsDir, function (err) { console.log(err); workbook.xlsx.writeFile(downloadsDir + '/temp.xlsx').then(function() { console.log('file is written'); var file = downloadsDir + '/temp.xlsx'; // fs.emptyDir(downloadsDir + '/', function (err) { // if (err) return console.error(err) // console.log('success!') // }); res.send(file); }); }); } catch(err) { console.log('OOOOOOO this is the error: ' + err); } }); 

这段代码是从我的公共javascript调用ajax函数

 $('.filter-accounts-btn').click(function(){ $.ajax({ type: 'post', url: '/accounts/filter', success: function(data) { console.log('------- data: ' + data); window.open(data, '_blank'); }, error: function(err) { console.log('------------ Error: ' + err); } }); }); 

但它似乎并不奏效。 很明显,它有什么问题。 当我在Heroku上运行我的应用程序时,打开的新页面具有以下url:

https://myapp.com/app/downloads/temp.xlsx

它显示我错误。 我也尝试使用一个名为open的npm模块,我只是打开用户的excel。 但它导致应用程序崩溃。

 open(file, function (err) { if ( err ) throw err; }); 

在本地进行testing时,会打开excel。

有一个更好的方法吗? 另外,如何知道用户是否下载了该文件? 现在它被保存在下载文件夹中,但是我想在文件被用户下载后立即清空该文件夹(使用注释的代码)。

*************编辑*********************

build议,我已经尝试了这个新的代码

 workbook.xlsx.writeFile(tempfile('.xlsx')).then(function() { console.log('file is written'); res.download(tempfile('.xlsx'), function(err){ console.log('---------- error downloading file: ' + err); }); }); 

res.downlaod引发错误

在这里输入图像说明

错误:ENOENT,stat'/var/folders/nk/2w94bk3j5fs976d_dj5vwsvr0000gn/T/54f77d41-db1e-4dcf-8aea-7f88d682c436.xlsx'

它不能find临时文件?

第一个build议是,如果不想持续很长时间,则停止将代码存储在代码中。 更好的方法是使用机器的临时目录并让操作系统清洁。 您可以使用tempfile来生成临时文件的完整path。

第二个build议是避免拆分文件生成和下载步骤。 您可以使用服务器上的res.download() api来指示浏览器直接向用户呈现下载窗口。 也就是说,不要向浏览器发送要下载的文件名,而是直接发送文件内容进行下载,并发送一个特殊的标题来指示客户端浏览器希望客户端下载文件。

后者要求你在浏览器上修改Jquery(?,纠正我,如果我错了)代码。 一旦发布了发布请求并收到服务器响应,浏览器应该直接显示下载对话框。

尝试这个:

 var tmp = tempfile('.xlsx'); workbook.xlsx.writeFile(tmp).then(function() { console.log('file is written'); res.download(tmp, function(err){ console.log('---------- error downloading file: ' + err); }); });