Jquery 在ajax success node.js上下载文件

Jquery 在ajax success node.js上下载文件,jquery,ajax,node.js,csv,Jquery,Ajax,Node.js,Csv,我正在使用node.js构建一个应用程序,它需要允许用户下载.csv文件 问题-当用户单击按钮时,应用程序不会将文件作为附件发送到客户端。但是,如果客户端直接转到API链接,则文件将下载。例如,如果用户转到localhost:3000/api/exportmetric,则a文件将作为附件发送到客户端。但如果该路由作为AJAX请求被命中,则不会发生任何事情 用户流: 1) 用户单击一个按钮 2) 应用程序向服务器发出AJAX GET请求 3) 服务器从数据库检索数据 4) 服务器将数据解析为.cs

我正在使用node.js构建一个应用程序,它需要允许用户下载.csv文件

问题-当用户单击按钮时,应用程序不会将文件作为附件发送到客户端。但是,如果客户端直接转到API链接,则文件将下载。例如,如果用户转到
localhost:3000/api/exportmetric
,则a文件将作为附件发送到客户端。但如果该路由作为AJAX请求被命中,则不会发生任何事情

用户流:

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
设置为下载url将下载文件

window.location = '/path/to/download?arg=1';
另一个稍微不同的版本是打开一个带有下载路径的新选项卡

window.open('/path/to/download', '_self');
2。虚拟链接点击

使用HTML5,您可以指定链接的
download
属性。单击该链接(甚至以编程方式)将触发url的下载。链接甚至不需要是DOM的一部分,您可以动态创建它们

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
库,它已经完成了所有这一切--


两步下载

您经常看到的另一个约定是两步下载,其中信息以已知url发送到服务器,服务器返回生成的url或id,可用于下载文件

window.location = '/path/to/download?arg=1';
如果您希望url是可以共享的,或者您必须向下载生成器传递许多参数,或者只想通过
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;
    }
});

为了补充Brendan的答案,我想出了第三种可行的方法:

1-在DOM中创建临时表单

2-在表格中填写我们想发布的数据(如发布请求)

3-发送表格

4-从DOM中删除表单

下面是我在JS中是如何做到这一点的

$(“#buybtn”)。单击(函数(){
url=“localhost:8080/”;
//我们创建一个表单
var form=document.createElement(“表单”);
//将方法设置为Post
form.setAttribute(“方法”、“帖子”);
//我们设置要执行的操作
form.setAttribute(“action”,url+“api2”);
//以下变量包含要发送的数据
参数={
姓名:“姓名”,
年龄:“年龄”
};
//我们迭代params中的可用字段
//并将数据设置为手动填写表单
for(参数中的变量键){
if(参数hasOwnProperty(键)){
var hiddenField=document.createElement(“输入”);
setAttribute(“类型”、“隐藏”);
setAttribute(“名称”,键);
setAttribute(“值”,参数[key]);
//我们在表单中插入每个元素
表格.appendChild(hiddenField);
}
}
//我们将表单附加到DOM中
文件.正文.附件(表格);
//我们提交表格
表单提交();
//我们删除创建的元素
文件.body.removeChild(表格);
});
在这篇文章中,学分归Rakesh Pai:


我希望它对你也有用

不用ajax就可以做到这一点<代码>别想太多了!是的,但最终我需要使用AJAX将数据发送到我的服务器,以查询需要下载到csv文件中的某些类型的数据。您也可以使用GET和锚定标记发送数据。使用ajax的问题在于,您无法直接下载ajax请求的响应。相反,您必须将其分为两个步骤:服务器存储文件,并将url发送到客户端进行下载,然后在下载完成后将其删除,这有点复杂。在这一点上,再次放弃ajax并发布表单或访问iframe将更加容易。我明白了,您能澄清一下
使用get和锚定标记发送数据吗?或者告诉我在哪里可以找到更多关于它的信息?