通过Spring MVC下载带有ajax()POST请求的文件

我尝试下载文件。 该操作由ajax()发布请求触发。 请求以json格式将数据发送到控制器。 控制器生成文件(字节)并将其发回。

java脚本:

function getLicenseFile() { $.ajax({ type: 'POST', url: '/licenses/rest/downloadLicenseFile', dataType: 'json', contentType: 'application/json;charset=UTF-8', data: ko.mapping.toJSON(licenseModel), success: function (data) { console.log("in sucess") }, error:function (xhr, ajaxOptions, thrownError){ console.log("in error") } }); } 

控制器:

 @RequestMapping(value = "/licenses/rest/downloadLicenseFile", method = RequestMethod.POST) @ResponseStatus(value=HttpStatus.OK) @ResponseBody public void createLicenseFile(@Valid @RequestBody License license, HttpServletResponse response) throws Exception { logger.debug("Contoller License in: "+ license); byte[] licensedata = licenseEncodeDefaultService.createLicenseFile(license); logger.debug("licenseData: " + new String(licensedata)); response.setHeader("Content-Disposition", "attachment; filename=\"" + license.getCustomer() + ".license\""); response.getOutputStream().write(licensedata); response.flushBuffer(); } 

问题:
*浏览器应该打开一个下载框,但它不会发生
*响应在错误:ajax函数部分处理(但http状态正常)

那么我错了什么或者这样做的正确方法是什么?

只需发送一个文件的URL作为响应,然后在success回调中“访问”它。

 function getLicenseFile() { $.ajax({ type: 'POST', url: '<%=request.getContextPath()%>/licenses/rest/downloadLicenseFile', dataType: 'json', contentType: 'application/json;charset=UTF-8', data: ko.mapping.toJSON(licenseModel), success: function (data) { window.open(data.fileUrl); // or window.location.href = data.fileUrl; }, error:function (xhr, ajaxOptions, thrownError) { console.log("in error"); } }); } 

应该由服务器设置data.fileUrl以说明客户端从何处获取文件。

所以你的服务器会发送一个像JSON一样的响应

 { "fileUrl": "http://mysite.com/files/0123456789" } 

@ will824正如你所问,我会发布自己的解决方案。

我在控制器中使用了一种解决方法,并将文件临时保存在文件系统(/ tmp)中。 我分两步拆分了这个function。 创建和下载。 这不是很好,但对我来说足够好。

Controller(创建文件,将保存在服务器文件系统中):

 @RequestMapping(value = "/licenses/rest", method = RequestMethod.PUT) @ResponseStatus(value=HttpStatus.OK) @ResponseBody public String createLicenseFile(@Valid @RequestBody License license) throws Exception { // create encrypted license file and send the name back to view String fileName = licenseEncodeDefaultService.createLicenseFile(license); return fileName; } 

控制器(下载文件):

 @RequestMapping(value = "/licenses/downloadFile/{file}", method = RequestMethod.GET) public void downloadLicenseFile(@PathVariable("file") String file, HttpServletResponse response) throws Exception { // create full filename and get input stream File licenseFile = new File ("/tmp/" + file); InputStream is = new FileInputStream(licenseFile); // set file as attached data and copy file data to response output stream response.setHeader("Content-Disposition", "attachment; filename=\"" + file + ".license\""); FileCopyUtils.copy(is, response.getOutputStream()); // delete file on server file system licenseFile.delete(); // close stream and return to view response.flushBuffer(); } 

JavaScript的:

 function getLicenseFile() { //console.log(ko.mapping.toJSON(licenseModel)); $.ajax({ type : 'PUT', url : '${pageContext.request.contextPath}/licenses/rest', dataType : 'text', contentType : 'application/json;charset=UTF-8', data : ko.mapping.toJSON(licenseModel), success : function(data) { window.location.href = '${pageContext.request.contextPath}/licenses/downloadFile/' + data; }, error : function(xhr, ajaxOptions, thrownError) { // error handling } }); } 

如果您想要没有更改URL的下载文件,可以使用ajax以编程方式调用form.submit()。

使用Javascript:

function downloadFileUsingForm(url) { var form = document.createElement("form"); form.method = "post"; form.action = url; document.body.appendChild(form); form.submit(); document.body.removeChild(form); } downloadFileUsingForm("/YourController/DownloadFile");
function downloadFileUsingForm(url) { var form = document.createElement("form"); form.method = "post"; form.action = url; document.body.appendChild(form); form.submit(); document.body.removeChild(form); } downloadFileUsingForm("/YourController/DownloadFile"); 

控制器:

[HttpPost] public ActionResult DownloadFile() { string content = "Some Values"; byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(content); return File(bytes, System.Net.Mime.MediaTypeNames.Application.Octet, "file.txt"); }
[HttpPost] public ActionResult DownloadFile() { string content = "Some Values"; byte[] bytes = System.Text.UTF8Encoding.UTF8.GetBytes(content); return File(bytes, System.Net.Mime.MediaTypeNames.Application.Octet, "file.txt"); } 

正如评论所说,你不能用ajax调用来做,但是你可以用普通的Javascript来做。

 function getLicenseFile() { var downloadUrl = "${pageContext.request.contextPath}/licenses/rest/downloadLicenseFile"; // (optionally) provide the user with a message that the download is starting window.location.href = downloadUrl; } 

请注意${pageContext.request.contextPath}的使用,它比<%=request.getContextPath()%>

Ajax不会帮助您尝试隐藏表单方法

 

通过单击下载按钮提交表单将json传递给表单字段

$( ‘#formid’)提交()。

然后在服务器端

 response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment; filename=filnemae.fileformat"); ServletOutputStream out = res.getOutputStream(); 

在输出流上写入然后关闭或刷新

如果您通过server.xml中的 post update postize发送大数据