以下是我的工作流程:
在按钮单击事件中,我将搜索结果导出到.csv文件,该文件将保存到服务器。保存文件后,我想将其发送到浏览器下载。使用此问题How to handle conditional file downloads in meteor.js,我创建了一个在保存文件返回的方法之后调用的方法。这是方法:
exportFiles: function(file_to_export) {
console.log("to export = "+file_to_export);
Meteor.Router.add('/export', 'GET', function() {
console.log('send '+file_to_export+' to browser');
return [200,
{
'Content-type': 'text/plain',
'Content-Disposition': "attachment; filename=" + this.request.query.file
}, fs.readFileSync( save_path + this.request.query.file )];
});
}
然而,我的问题是如何调用该路线?使用.Router.to('/export?file=filename.ext')
不起作用,并导致用户离开当前页面。我希望这对用户来说是无缝的,我不希望他们知道他们被重定向。在有人要求之前,save_path
在方法之外被声明,所以它确实存在。
答案 0 :(得分:6)
我已经知道了!但是,它需要使用一些额外的包。首先,让我更清楚地描述工作流程:
我们网站上的用户执行搜索。在随后的搜索结果页面上,存在一个按钮,允许用户将他/她的搜索结果导出到.csv文件。然后将该文件导出到浏览器以供下载。
我们遇到的一个问题是,如果将文件写入服务器,请确保只有导出文件的用户才能查看该文件。为了控制谁对文件具有可见性,我使用了陨石包,CollectionFS(mrt add collectionFS或来自github的克隆)。该包将文件缓冲区写入mongo集合。保存时提供“所有者”字段可让您控制访问权限。
无论文件是如何创建的,无论是通过上传表单保存到服务器还是像我使用json2csv软件包一样动态生成,该文件必须作为缓冲区流式传输到CollectionFS。
var userId = Meteor.userId()
var buffer = Buffer(csv.length); //csv is a var holding the data for write
var filename = "name_of_file.csv";
for ( var i=0; i<csv.length; i++ ) {
buffer[i] = csv.charCodeAt(i);
}
CollectionFS.storeBuffer(filename, buffer, {
contentType: 'text/plain',
owner: userId
});
所以在这一点上,我已经获取了我的数据文件,并将其作为缓冲区流式传输到mongo集合中。因为我的数据存在于var csv的内存中,所以我通过循环遍历每个字符将其作为缓冲区流式传输。如果这是一个保存在物理磁盘上的文件,我会使用fs.readFileSync(file)并将返回的缓冲区发送到CollectionFS.storeBuffer()。
既然文件在mongo中与所有者一起保存为缓冲区,我可以限制通过发布可以下载/更新/删除文件甚至知道该文件存在的CollectionFS集合。
为了从mongo读取文件并将文件发送到浏览器进行下载,需要另一个Javascript库:FileSaver(github)。
使用CollectionFS中的retrieveBlob方法,通过提供引用mongo集合中文件的_id,将文件作为blob从mongo中提取出来。 FileSaver有一个方法,saveAs接受blob,并导出到浏览器以下载为指定的文件名。
var file = // file object stored in meteor
CollectionFS.retrieveBlob(file._id, function(fileItem) {
if ( fileItem.blob ) saveAs(fileItem.blob, file.filename);
else if ( fileItem.file ) saveAs(fileItem.file, file.filename);
});
我希望有人会觉得这很有用!
答案 1 :(得分:0)
如果您的路线有效,那么当您的方法返回时,您可以打开一个包含文本文件链接的新窗口。
您已添加内容处置标题,因此该文件应始终要求保存。
即使您只是重定向到该文件,因为它具有这些内容处置标题,它会要求保存并且不会中断您的会话。