/* *@url --string下載路徑 *@filename --string文件名稱*/ downLoadProcess(url,filename){ filename = filename || 'xxx.csv'; // 創建xhr對象 var req = new XMLHttpReque ...
可以通過設置一個XMLHttpRequest對象的 responseType 屬性來改變一個從伺服器上返回的響應的數據類型。可用的屬性值為空字元串 (預設), "arraybuffer", "blob", "document", 和 "text".
response 屬性的值會根據 responseType 屬性的值的不同而不同, 可能會是一個 ArrayBuffer, Blob, Document, string,或者為NULL(如果請求未完成或失敗)。
新版本的 XMLHttpRequest 對象,傳送數據的時候,有一個 progress 事件,用來返回進度信息。
它分成 上傳 和 下載 兩種情況。下載的 progress 事件屬於 XMLHttpRequest 對象,上傳的 progres s事件屬於 XMLHttpRequest.upload 對象。
1、前端代碼:
downLoadProcess(url,filename){ filename = filename || 'xxx.csv'; // 創建xhr對象 var req = new XMLHttpRequest(); //向伺服器發送請求 open() send() req.open("POST", url, true); //(method-GET/POST ,url, async) req.setRequestHeader("Content-type","application/x-www-form-urlencoded");//POST時需要傳遞 //監聽進度事件 xhr.addEventListener("progress", uploadProgress, false); xhr.addEventListener("load", uploadComplete, false); xhr.addEventListener("error", uploadFailed, false); xhr.addEventListener("abort", uploadCanceled, false); /* XMLHttpRequest 的 responseType 屬性 一個枚舉類型的屬性,返迴響應數據的類型,只能設置非同步的請求 1、'' -- DOMString (預設); UTF-16 2、arraybuffer -- arraybuffer對象,即類型化數組 3、blob -- Blob對象, 二進位大數據對象 4、document -- Document對象 5、json 6、text */ //設置返回數據的類型 req.responseType = "blob"; req.onreadystatechange = function () { //同步的請求無需onreadystatechange if (req.readyState === 4 && req.status === 200) { var filename = $(that).data('filename'); if (typeof window.chrome !== 'undefined') { // Chrome version var link = document.createElement('a'); link.href = window.URL.createObjectURL(req.response); link.download = filename; link.click(); } else if (typeof window.navigator.msSaveBlob !== 'undefined') { // IE version var blob = new Blob([req.response], { type: 'application/force-download' }); window.navigator.msSaveBlob(blob, filename); } else { // Firefox version var file = new File([req.response], filename, { type: 'application/force-download' }); window.open(URL.createObjectURL(file)); } } }; req.send("fname=Henry&lname=Ford"); } function uploadProgress(evt) { if (evt.lengthComputable) {
/*後端的主要時間消耗都在查詢數據和生成文件,所以可以設置預設值,直到真正到達下載的進度,再開始走進度條*/ var percent = Math.round(evt.loaded * 100 / evt.total); document.getElementById('progress').innerHTML = percent.toFixed(2) + '%'; document.getElementById('progress').style.width = percent.toFixed(2) + '%'; }else { document.getElementById('progress').innerHTML = 'unable to compute'; } } function uploadComplete(evt) { /* 伺服器端返迴響應時候觸發event事件*/ document.getElementById('result').innerHTML = evt.target.responseText; } function uploadFailed(evt) { alert("There was an error attempting to upload the file."); } function uploadCanceled(evt) { alert("The upload has been canceled by the user or the browser dropped the connection."); }
2、後臺處理介面
public void aaa() { string result = string.Empty; for (int i = 1; i <= 6000; i++) { result += i.ToString(); int len = result.Length; Response.Headers.Add("Content-Length", len.ToString()); Response.Headers.Add("Content-Encoding", "UTF-8"); Response.Write(result); } }
註意到 ::
Response.Headers.Add("Content-Length", len.ToString());
Response.Headers.Add("Content-Encoding", "UTF-8");
寫出 http 頭時候,附加 “Content-Length”和Content-Encoding,
這樣 JS 端的 progress 事件的 event.lengthComputable 值才會為 true
, event.total 才會在數據傳輸完畢之前取得值,
否則 event.lengthComputable 值會返回 false
, event.total 在數據完成之前值都是0
。