在ajax success node.js

时间:2016-02-02 21:39:29

标签: jquery ajax node.js csv

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

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

用户流程:

1)用户点击按钮

2)App向服务器发出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);
    });
});

2 个答案:

答案 0 :(得分:9)

基本上有两种流行的方式来下载文件。

<强> 1。设置window.location

window.location设置为下载网址将下载该文件。

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);

所有浏览器都不支持此功能,因此即使您要使用此方法,也必须放弃对某些浏览器的支持或回退到第一种方法。

幸运的是,this excellent answer引用了一个很棒的小js库来完成所有这些工作 - http://pixelscommander.com/polygon/downloadjs/#.VrGw3vkrKHv

downloadFile('/path/to/download');

两步下载

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

如果您希望网址可以共享,或者您必须将大量参数传递给下载生成器,或者只是想通过POST请求来执行此操作,这将非常有用。 / p>

$.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;
    }
});

答案 1 :(得分:0)

为了补充布伦丹的答案,我想出了第三个可行的方法:

1-在DOM中创建临时表单

2-用我们要发布的数据填写表单(如在发布请求中一样)

3-发送表格

4-从DOM中删除表单

这是我在JS中的操作方式

  $("#buybtn").click(function(){
    url = "localhost:8080/";
    // we create a form
    var form = document.createElement("form");
    // set the method to Post
    form.setAttribute("method", "post");
    // we set the action to be performed
    form.setAttribute("action", url + "api2");

    // the following variables contains the data to send
    params = {
        name : "name",
        age : "age"
    };

    // we iterate over the available fields in params
    // and set the data as if we are manually filling the form
    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            // we insert each element in the form
            form.appendChild(hiddenField);
        }
    }

    // we append the form to the DOM
    document.body.appendChild(form);
    // we submit the form
    form.submit();
    // we delete the created elements
    document.body.removeChild(form);
  });

本文的信用归Rakesh Pai负责:JavaScript post request like a form submit

我希望它也对您有用!