總結下實際開發過程當中使用過的文件下載方法: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(); }