Spring - 将响应下载为文件

mch*_*bok 33 spring angularjs

我正在使用AngularJS和Spring编写应用程序.我想向服务器发送请求并下载从控制器返回的响应作为文件.在控制器中,我有csv文件的内容(作为字符串),即1;2;3;4(1行,4列).将此响应作为文件下载的最简单方法是什么?

下面,我发布了我的简化代码.在Spring控制器中:

@RequestMapping(value = "/csv", method = GET)
@ResponseBody
public String getCsvFile() {
    return getCsvContent();
}
Run Code Online (Sandbox Code Playgroud)

在javascript(AngularJS)

return $http({method: 'GET', url: 'csv/'});
Run Code Online (Sandbox Code Playgroud)

我也试图写入响应流(下面),设置标题,但在客户端我总是把这个内容作为字符串 - 而不是作为要下载的文件.

@RequestMapping(value = "/csv", method = GET)
@ResponseBody
public void getCsvFile(HttpServletResponse response) {
    response.setContentType("application/csv");
    response.setHeader("Content-Disposition", "attachment; filename=file.csv");
    response.setContentLength(getCsvContent().getBytes().length);
    ServletOutputStream out = response.getOutputStream();
    out.write(getCsvContent());
    out.flush();
    out.close();
}
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何正确编写控制器的方法,以便在客户端下载响应作为文件?

dnc*_*253 25

您无法通过XHR请求下载文件(这是Angular提出请求的方式).请参阅为什么使用ajax请求无法下载文件?您需要转到URL $window.open或执行此处显示的iframe技巧:使用JSON数据通过POST下载文件的JavaScript/jQuery

  • 这似乎不正确,因为您可以使用Blob来保存文件,例如:http://stackoverflow.com/questions/19327749/javascript-blob-filename-without-link (9认同)

XML*_*XML 8

我自己也在努力解决这个问题,试图让它从服务器上运行.不能.代替...

  1. 澄清@ dnc253的答案,$window.open(URL)是让Angular应用程序在另一个窗口中打开给定URL的方法.(它实际上只是通用的可测试角度代理window.open().)这是一个很好的解决方案,保留您的历史记录,并获取文件下载,如果支持,可能会在新的浏览器窗口中呈现它.但它经常遇到弹出窗口拦截器,这对可靠性来说是一个巨大的问题.用户通常根本不理解他们正在发生什么.因此,如果您不介意立即使用当前窗口下载文件,您可以简单地使用同样有效的通用JavaScript方法:location.href = "uriString"这对我来说就像一个魅力.Angular甚至没有意识到发生过任何事情.一旦我的POST/PUT操作完成,我就在一个promise处理程序中调用它.如果需要,让POST/PUT返回要调用的URL,如果你还不能推断它.您将获得与用户相同的行为,就像它为响应PUT/POST而下载一样.例如:

    $http.post(url, payload).then(function(returnData){
        var uriString = parseReturn(returnData);
        location.href="uriString"
    })
    
    Run Code Online (Sandbox Code Playgroud)
  2. 实际上,您可以直接从XHR请求下载内容,但它需要完全支持HTML5文件API,并且通常比它的价值更麻烦,除非您需要在文件上对用户可用之前对文件执行本地转换.(遗憾的是,我没有时间提供详细信息,但还有其他SO帖子关于使用它.)