总结下实际开发过程当中使用过的文件下载方法:javascript
刚开始接触$.ajax()时 欣喜若狂,觉得全部的异步交互均可以用它来操做,直到流文件。具体的场景是:html
首先想到的是经过$.ajax来进行操做,由于和后台交互的参数不少,它的参数形式能够用键值对对象的形式,很方便,html5
可是怎么操做都不行,不报错,可是文件就是不能下载,又想到设置dataType的形式,发现没文件流的形式,心中java
一万个…….jquery
废话少说,总结方法:web
(1)经过a标签的形式,应该能够知足大多的需求。ajax
就是经过设置href属性,点击a标签,就能够下载成功。PS:a的html5中download的属性,能够直接重命名文件。数组
<button type="button" onclick="download()">导出</button> function download() { var a = document.createElement('a'); var url = 'download/?filename=aaa.txt'; var filename = 'data.xlsx'; a.href=url; a.download = filename; a.click() }
(2)经过window.locationapp
(3)建立iframe异步
var elemIF = document.createElement("iframe"); elemIF.src = "../lib/TemplateCollection/" + ExcelName + ".xls"; elemIF.style.display = "none"; document.body.appendChild(elemIF);
以上三种方法指向后台返回文件流的方法,或者具体的实际文件路径,均可如下载文件。
(4)HTML5中blob对象
不少人都在说第这种方法能够知足,实际上是错误方式
<button type="button" onclick="download()">导出</button><br> function download() { var url = 'download/?filename=aaa.txt'; $.get(url, function (data) { console.log(typeof(data)) blob = new Blob([data]) var a = document.createElement('a'); a.download = 'data.xlsx'; a.href=window.URL.createObjectURL(blob) a.click() }) }
这种方式保存的文件是不能打开的,console.log(typeof(data))会看到是string类型(乱码的),缘由是jquery将返回的数据转换为了string,不支持blob类型。
正确方式:
<button type="button" onclick="download()">导出</button><br> function download() { var url = 'download/?filename=aaa.txt'; var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); // 也可使用POST方式,根据接口 xhr.responseType = "blob"; // 返回类型blob // 定义请求完成的处理函数,请求前也能够增长加载框/禁用下载按钮逻辑 xhr.onload = function () { // 请求完成 if (this.status === 200) { // 返回200 var blob = this.response; var reader = new FileReader(); reader.readAsDataURL(blob); // 转换为base64,能够直接放入a表情href reader.onload = function (e) { // 转换完成,建立一个a标签用于下载 var a = document.createElement('a'); a.download = 'data.xlsx'; a.href = e.target.result; $("body").append(a); // 修复firefox中没法触发click a.click(); $(a).remove(); } } }; // 发送ajax请求 xhr.send() }
实际中碰到的一种状况是:
Action代码:
if(inputStream != null) fileLength=inputStream.available(); else fileLength=0; String method=request.getMethod(); String userAgent=request.getHeader("User-Agent"); Browser browser=Browser.fromUserAgent(userAgent); this.contentType=FileContentType.buildContentType(filename); if("POST".equals(method)) { filename=URLEncoder.encode(filename, "UTF-8"); } else { switch(browser.getType()) { case Browser.IE: filename=URLEncoder.encode(filename, "UTF-8"); break; default: filename=new String(filename.getBytes(),"ISO8859-1"); break; } } this.contentDisposition="attachment;"; this.contentDisposition+="filename=\""+filename+"\""; response.setHeader("accept-ranges", "bytes");
xml配置:
<action name="importAndExportDownload" class="cost-importAndExportAction" method="download"> <result type="stream"> <param name="contentDisposition">${contentDisposition}</param> <param name="contentType">${contentType}</param> <param name="inputName">inputStream</param> </result> </action>
后台返回正常的文件流:直接下载
后台抛出异常throw new exception,获取错误信息,而且用easyui的dialog对话框展现:
错误信息也是流的形式返回,数据格式内容示例以下:
"<html> <body bgcolor="white"> <span class="bold">备份文件大小异常,可从新尝试备份操做!文件大小:6291 检测最小值:700000<br></span> </body> </html> {"data":null,"dataFieldList":[],"dataMap":[],"message":"备份文件大小异常,可从新尝试备份操做!文件大小:6291 检测最小值:700000<br>","returnCode":-20000000}"
JS代码:
function postDownload(url){ var request = new XMLHttpRequest(); request.open("POST", url); request.responseType = "blob"; // 返回类型blob request.onload = function() { if (this.status === 200) { var blob = request.response; var URL = window.URL || window.webkitURL; try{ //正常文件下载 var name = request.getResponseHeader("Content-disposition"); var filename = decodeURI(name.substring(21, name.length-1)); var type=request.getResponseHeader("Content-Type"); var blobUrl= URL.createObjectURL(blob); var a = document.createElement('a'); a.download = filename; a.href = blobUrl;//e.target.result; a.click(); $(a).remove(); }catch(e){ var reader = new FileReader(); reader.readAsText(blob); // 转换为base64 reader.onload = function (e) { $.messager.alert('提示',e.target.result.split("{")[0].trim(),'info'); } // $('#myErrorDiv').window('close'); } } } request.send(); }