總結下實際開發過程中使用過的文件下載方法:
剛開始接觸$.ajax()時 欣喜若狂,以為所有的異步交互都可以用它來操作,直到流文件。具體的場景是:
后台操作文件 ,以二進制流的形式,返回到前台(我實際的場景是導出Excel文件) context.Response.BinaryWrite(二進制數組);
首先想到的是通過$.ajax來進行操作,因為和后台交互的參數很多,它的參數形式可以用鍵值對對象的形式,很方便,
但是怎么操作都不行,不報錯,但是文件就是不能下載,又想到設置dataType的形式,發現沒文件流的形式,心中
一萬個…….
廢話少說,總結方法:
(1)通過a標簽的形式,應該可以滿足大多的需求。
就是通過設置href屬性,點擊a標簽,就可以下載成功。PS:a的html5中download的屬性,可以直接重命名文件。
固定的:
<a download="data.xls" href="file.ashx?paramone=canshuyi"> </a>
動態的:
<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.location
window.location = "../handler/OperateExcel/OutExcelCom.ashx?tablename=canshuyi"
(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>
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>
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() }
參考:
https://my.oschina.net/watcher/blog/1525962
http://www.cnblogs.com/cdemo/p/5225848.html