Javascript 启动从AJAX web服务下载动态生成的CSV文件

Javascript 启动从AJAX web服务下载动态生成的CSV文件,javascript,ajax,web-services,spring-mvc,csv,Javascript,Ajax,Web Services,Spring Mvc,Csv,我需要将用户输入(最好是通过自定义DTO)提交到后端,以便动态生成CSV文件供用户下载。我将SpringMVC与基于web服务的客户端应用程序一起使用 我对这个问题的潜在原因做了一些研究。我知道我不能使用AJAX来提示下载。无论我将内容配置设置为什么,它都会将CSV数据作为字符串返回到浏览器。经常提出的解决方案是通过JavaScript将用户重定向到下载链接。我认为这对我不起作用,因为1)它不是静态下载,2)参数很复杂,3)我需要使用CAC PKI安全性(我将通过AJAX web服务调用实现)

我需要将用户输入(最好是通过自定义DTO)提交到后端,以便动态生成CSV文件供用户下载。我将SpringMVC与基于web服务的客户端应用程序一起使用

我对这个问题的潜在原因做了一些研究。我知道我不能使用AJAX来提示下载。无论我将内容配置设置为什么,它都会将CSV数据作为字符串返回到浏览器。经常提出的解决方案是通过JavaScript将用户重定向到下载链接。我认为这对我不起作用,因为1)它不是静态下载,2)参数很复杂,3)我需要使用CAC PKI安全性(我将通过AJAX web服务调用实现)

下面是我为测试这个概念而创建的一个简单方法

@RequestMapping(value = "committees/exportCommittees", method = RequestMethod.POST, consumes = "application/json")
public void getMailingAddressesByCommittee(
        @RequestBody final ExportMailingLabelDTO exportMailingLabelDTO,
        HttpServletResponse response) throws JsonParseException,
        JsonMappingException, IOException {
    // In future, ExportMailingLabelDTO will be used to filter 
            // the returned data based on user input.


    String csvFileName = "mailmerge.csv";

    response.setContentType("text/csv");

    String headerKey = "Content-Disposition";
    String headerValue = String.format("attachment; filename=\"%s\"",
            csvFileName);
    response.setHeader(headerKey, headerValue);

    StringWriter sw = new StringWriter();

    CSVWriter csvWriter = new CSVWriter(sw, CSVWriter.DEFAULT_SEPARATOR,
            CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.NO_ESCAPE_CHARACTER);
    String[] columns = new String[] { "ID" };
    csvWriter.writeNext(columns);

    String[] values;

    values = new String[] { "1", "2", "3" };
    csvWriter.writeNext(values);
    PrintWriter out = response.getWriter();
    out.println(sw.toString());
    csvWriter.close();
}
ExportMailLabelDTO包含根据用户输入过滤返回数据的信息

当我通过AJAX web服务调用此方法时,它会通过字符串将数据返回到浏览器,但不会提示下载

function exportMailingAddressesByCommittee(committeeList) {
var seen = [];
var data = $.ajax({
    type : "POST",
    contentType : 'application/json',            
    url : urlCommitteesBase + "exportCommittees",
    data : JSON.stringify(committeeList, function(key, val) {
           if (typeof val == "object") {
                if (seen.indexOf(val) >= 0)
                    return
                seen.push(val);
            }
            return val; })
});
return data;
}
如果我在删除参数的情况下使用了一个稍微修改过的方法,并将其直接放在URL栏中,它将提示下载


那么,有没有办法通过AJAX web服务来实现这一点呢?这是否只能通过非AJAX web服务调用实现

您可以在iframe中进行下载。它应该像一个单独的浏览器窗口一样工作。我想我需要先保存报表,然后保存到服务器端,以便在URL请求中提供服务,对吗?我不希望保存任何报表,因为它们是动态的。您是否建议将请求存储在后端的会话中?一旦用户完成,您就可以将其从会话中删除吗?实际上,您不必在服务器上有一个物理文件来提供服务。我的意思是,您可以在运行时生成一个文件,并将其直接写入客户端,从而将其保存到服务器上的磁盘上,然后将其发送到客户端。我编写了一个方法,该方法可根据请求将动态文件直接发送到URL。不过,它的安全性更为宽松。你知道如何在URL本身的用户名/密码之外保护它吗?我们使用的是PKI安全性,我通常通过AJAX请求传递它。另外,如果不使用AJAX,我还没有成功地将复杂的参数传递到方法中……您是否使用嵌入URL的参数?抱歉搞混了…除了Spring Security,我没有使用任何东西。为此,您应该确保文件下载的URL包含在安全过滤器中,Spring安全性应该负责确保请求来自经过身份验证的源。对于参数,有很多方法可以做到这一点。你必须更加明确你的最终目标是什么。