我尝试下载文件。该操作由ajax()发布请求触发。请求以json格式将数据发送到控制器。控制器生成文件(字节)并将其发回。
java脚本:
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) {
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状态正常)
那么我错了什么或者做到这一点的正确方法是什么?
答案 0 :(得分:15)
只需发送回复的文件网址,然后在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"
}
答案 1 :(得分:6)
@ will824正如你所问,我会发布自己的解决方案。
我在控制器中使用了一种解决方法,并将文件临时保存在文件系统(/ tmp)中。我分两步拆分了这个功能。创建和下载。 这不是很好,但对我来说已经足够了。
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
}
});
}
答案 2 :(得分:4)
如果您想要没有更改网址的下载文件,可以使用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");
控制器:
[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");
}
答案 3 :(得分:2)
正如评论所说,你不能用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()%>
。
答案 4 :(得分:0)
Ajax不会帮助您尝试隐藏表单方法
<form action='../servletname' method='POST' id='formid'>
<input type='hidden' value='' name='name' id='id'/>
<input type='hidden' value=' ' name='name' id='id' />
</form>
通过表单字段传递json 点击下载按钮提交表单
$(&#39;#formid&#39)。提交();
然后在服务器端
response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment; filename=filnemae.fileformat");
ServletOutputStream out = res.getOutputStream();
写入ouput流然后关闭或刷新
如果您通过post 更新postize in server.xml
发送大量数据