一、ajax文件下载问题:

最近的做的一个文件导出功能,开始以为很简单。。。因为毕设做的就是这个主题,然而,我毕设似乎巧妙的躲过了最近遇到的这个问题:ajax没法实现文件下载

java 下载本项目中的excel文件乱码 java下载文件内容为空_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)了一下,发现:

java 下载本项目中的excel文件乱码 java下载文件内容为空_文件下载_02

分析:一般请求浏览器是会处理服务器输出的response,比如二进制形式,触发了浏览器打开保存文件对话框,生成png、文件下载等,,JQuery的ajax函数的返回类型只有xml、text、json、html等类型,没有“流”类型,所以ajax请求下载返回的内容应该是以文本的形式放在javascipt内存空间,可以通过javascript进行访问(以上输出的截图),但是无法保存到硬盘,因为javascript不能直接和硬盘交互,否则将是一个安全问题(这句话是网上参考的0.0)。

之后:于是将代码改写为form表单请求之后,发现就可以实现下载功能了。

java 下载本项目中的excel文件乱码 java下载文件内容为空_文件下载_03

二、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(),即接口别返回其他的,就负责文件的下载。但是这里还是要提出请求,如果非要返回东西该如何处理这个问题。。。