一、ajax文件下载问题:
最近的做的一个文件导出功能,开始以为很简单。。。因为毕设做的就是这个主题,然而,我毕设似乎巧妙的躲过了最近遇到的这个问题:ajax没法实现文件下载
我觉得这段代码没有任何问题(后端是一个文件下载接口),但是就是没法完成下载,debug过程中并没有报什么错误,但是也没有跳出下载位置选择框,那么这段代码的输出的东西去了哪里呢???
resp.setHeader("content-disposition", "attachment;filename="
+ URLEncoder.encode(name , "UTF-8")
+ .replaceAll("%28", "(").replaceAll("%29", ")"));
OutputStream out = resp.getOutputStream();
byte buffer[] = new byte[1024];
int len = 0;
// 循环将输入流中的内容读取到缓冲区当中
while ((len = in.read(buffer)) > 0) {
// 输出缓冲区的内容到浏览器,实现文件下载
out.write(buffer, 0, len);
}
// 关闭输出流
out.close();
于是在ajax中 console.info(data)了一下,发现:
分析:一般请求浏览器是会处理服务器输出的response,比如二进制形式,触发了浏览器打开保存文件对话框,生成png、文件下载等,,JQuery的ajax函数的返回类型只有xml、text、json、html等类型,没有“流”类型,所以ajax请求下载返回的内容应该是以文本的形式放在javascipt内存空间,可以通过javascript进行访问(以上输出的截图),但是无法保存到硬盘,因为javascript不能直接和硬盘交互,否则将是一个安全问题(这句话是网上参考的0.0)。
之后:于是将代码改写为form表单请求之后,发现就可以实现下载功能了。
二、response问题:
getOutputStream() has already been called for this response
即:response已经被其他对象调用了,导致无法继续使用这个response
分析:出现这个问题的原因是同时使用了response.getWriter()和response.getOutputStream(),网上说:tomcat6之后,在调用response.getOutputStream()方法时会判断是否已调用了requonse.getWriter()方法;在调用requonse.getWriter()方法时会判断是否已调用了response.getOutputStream()方法。
解决办法:其实最简单的解决这个问题最简单的方法就是不要使用response.getWriter(),即接口别返回其他的,就负责文件的下载。但是这里还是要提出请求,如果非要返回东西该如何处理这个问题。。。