我正在使用node.js构建一个应用程序,该应用程序需要允许用户下载.csv文件。
问题-当用户单击按钮时,应用程序不会将文件作为附件发送到客户端。但是,如果客户端直接转到API链接,则会下载文件。例如- 如果用户转到localhost:3000/api/exportmetric,该文件将作为附件发送到客户端。但是,如果将该路由作为AJAX请求命中,则什么也不会发生。
localhost:3000/api/exportmetric
用户流:
1)用户单击一个按钮
2)应用程序向服务器发出AJAX GET请求
3)服务器从数据库检索数据
4)服务器将数据解析为.csv文件
5)服务器将文件发送回客户端以作为附件下载。
我的代码:
client.js
$("#export_velocity").click(function(e) { console.log('export to velocity hit'); $.ajax({ url: 'http://localhost:3001/api/exportmetric', type: 'GET', success: function(response) { console.log(response); }, error: function(a, b, c) { console.log(a); console.log(b); console.log(c); } }); });
server.js
router.get('/api/exportmetric', function(req, res) { console.log('export metric hit'); var fields = ['first_name', 'last_name', 'age']; var fieldNames = ['First Name', 'Last Name', 'Age??']; var people = [ { "first_name": "George", "last_name": "Lopez", "age": "31" }, { "first_name": "John", "last_name": "Doe", "age": "15" }, { "first_name": "Jenna", "last_name": "Grassley", "age": "44" } ]; json2csv({ data: people, fields: fields, fieldNames: fieldNames }, function(err, csv) { res.setHeader('Content-disposition', 'attachment; filename=file.csv'); res.set('Content-Type', 'text/csv'); console.log(csv) res.status(200).send(csv); }); });
基本上有两种流行的下载文件的方式。
1套window.location
window.location
设置window.location为下载网址将下载文件。
window.location = '/path/to/download?arg=1';
与此版本略有不同的是,打开带有下载路径的新标签页
window.open('/path/to/download', '_self');
2.虚拟链接请点击
使用HTML5,您可以指定download链接的属性。单击链接(甚至以编程方式)将触发该URL的下载。链接甚至不需要成为DOM的一部分,您可以动态地使它们。
download
var link = document.createElement('a'); link.href = '/path/to/download'; link.download = 'local_filename.csv'; var e = document.createEvent('MouseEvents'); e.initEvent('click', true, true); link.dispatchEvent(e);
并非所有浏览器都支持此功能,因此,即使您要使用此方法,也必须放弃对某些浏览器的支持或回退到第一种方法。
幸运的是,这个出色的答案引用了一个很棒的小js图书馆,它已经完成了所有这些工作- http: //pixelscommander.com/polygon/downloadjs/#.VrGw3vkrKHv
js
downloadFile('/path/to/download');
两步下载
您经常会看到的另一种约定是两步下载,即以已知的URL将信息发送到服务器,然后服务器发回生成的URL或ID,可用于下载文件。
如果您希望url是可以共享的内容,或者必须将大量参数传递给下载生成器,或者只是想通过POST请求进行操作,则这很有用。
POST
$.ajax({ type: 'POST', url: '/download/path/generator', data: {'arg': 1, 'params': 'foo'}, success: function(data, textStatus, request) { var download_id = data['id']; // Could also use the link-click method. window.location = '/path/to/download?id=' + download_id; } });