今日需要對公司的代碼進行更新,發現之前有的文件丟失導致下載不到直接跳轉到一個空的頁面,第一反應是應該沒有用異步請求,直接用a標籤或者表單之類的處理下載文件請求了。
但是ajax似乎是不支持下載文件的,會把流信息當初文本類處理。。。自然不能還原文件數據。
通過測試發現原生ajax xhlHttpRequest可以處理流信息,具體在於它可以將請求中的數據變成blob對象進行讀取(好吧我一個後端的實在是不太清楚前段原理)。。。可以通過判斷http的status狀態來進行下載文件或者提示錯誤。
function downloadOnclick() {
var file=$("#realr0205").val();
var fileName=file;
if (file!=undefined&&file!=""&&file.indexOf("/")!=-1){
fileName=file.substr(file.lastIndexOf("/")+1);
}
var url = BASE_PATH+'/manage/filedownload?path='+file;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true); // 也可以使用POST方式,根據接口
xhr.responseType = "blob"; // 返回類型blob
// 定義請求完成的處理函數,請求前也可以增加加載框/禁用下載按鈕邏輯
xhr.onload = function () {
if (this.status == 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 = fileName;
a.href = e.target.result;
$("body").append(a); // 修復firefox中無法觸發click
a.click();
$(a).remove();
}
}else {
//此處是前端layiUI自帶的提示框,無視即可
$.confirm({
theme: 'dark',
animation: 'rotateX',
closeAnimation: 'rotateX',
title: false,
content: '未找到該文件',
buttons: {
confirm: {
text: '確認',
btnClass: 'waves-effect waves-button waves-light'
}
}
});
}
};
xhr.send();
}
參考:https://www.cnblogs.com/cdemo/p/5225848.html
另外網上也有一部分人說此方法不安全之類的,缺少判斷,容易被網絡攻擊,我覺得ajax可以帶上token,在http協議中加上header信息那原生xhr應該也可以做到吧,既然能做到帶上安全驗證信息,在後端驗證一下不就行了?
還有一部分人認爲這樣做太麻煩,直接通過A標籤或者表單進行實現,我覺得現在基本上哪個功能都會存在錯誤,存在錯誤就會產生意料之外的情況,大大降低用戶體驗感,所以異步請求加判斷纔是主流。
下面公司之前寫法,怪不得拿不到文件就不知道調到哪個頁面了。
jQuery.download = function (url, method, filedir) {
jQuery('<form action="' + url + '" method="' + (method || 'post') + '">' + // action請求路徑及推送方法
'<input type="text" name="path" value="' + filedir + '"/>' + // 文件路徑
'</form>')
.appendTo('body').submit().remove();
//var newTab = window.open('about:blank')
//newTab.location.href = url;
};