填坑之路:二進制數據流文件下載

痛點是保存服務端返回的二進制數據流文件。

由于之前遇到的都是服務端直接返回文件地址,前端直接 window.open(url) 下載保存的,所以初次遇到文件流保存的,也是很頭痛的。

response.png

初嘗試

直接再用老辦法試試?

window.open(res.data)

結果很尷尬,現象是從當前窗口 http://localhost:8083/#/list 新開了一個窗口 http://localhost:8083/[object%20ArrayBuffer]#/list ,并沒有下載任何文件。

再嘗試

總結之前的初嘗試,發現很愚蠢:res.data 是一個二進制文件流,而平時我們使用 window.open(),參數帶的是url,并不是任何其他格式的數據。

那么,我們接下來考慮,既然服務端返回的是一個二進制流,那么我們前端是不是有什么工具或者方法能夠接收并處理這種二進制流的呢?

一番了解,Blob對象跳入眼中:

Blob是一種JavaScript的對象類型,表示一個不可變、原始數據的類文件對象。HTML5的文件操作對象,其他操作二進制數據的API(比如File對象),都是建立在Blob對象基礎上的,繼承了它的屬性和方法。

完美對接。

let blob = new Blob([res.data], {type: "application/vnd.ms-excel"}); // 將服務端返回的文件流excel文件
let fileName = `資源${new Date().getTime()}.xls`; // 保存的文件名
this.downLoadFile(blob, fileName); 
/**
 * 下載文件流(兼容IE10)
 * @param {*} blob 
 * @param {*} fileName 
 */
 
downLoadFile (blob, fileName) {
    if (window.navigator.msSaveOrOpenBlob) { // IE10
        navigator.msSaveBlob(blob, fileName);
    } else {
        let link = document.createElement('a');
        link.style.display = 'none';

        link.href = URL.createObjectURL(blob); //創建一個指向該參數對象的URL
        link.download = fileName;
        link.click(); // 觸發下載
        URL.revokeObjectURL(link.href); // 釋放通過 URL.createObjectURL() 創建的 URL
    }
}

結果還可以,文件成功下載了(base64文件下載也可參照上述邏輯哦)。

但是,亂碼了。

messyCode.png

WTF,我要穩住,勝利近在咫尺。

三嘗試

總結再嘗試,現在的情況是文件能下載了,文件名也是我們正確的按我們指定的保存的,美中不足則是文件亂碼。

"嘿嘿嘿,二話不說,肯定是服務端的鍋。" 腦子里一直回蕩著這句話,在確保了自己是 UTF-8 接收的后,找后端小哥理論去了。結果很尷尬,小哥斷點保存后打開居然是正確的格式,現在壓力來到了我這邊。

服務端明確表示返回的是一個二進制數據流,我們前端接收也使用了 Blob,按理說是完美對接了,唯一有可能出錯的地方就是前端從服務端獲取到的數據類型并不是 Blob了,而從之前找后端小哥打臉的經歷我們可以確定服務端的response內容是沒有問題的,一番分析,確定了問題出在前端接收 ajax 上了。

果然,ajax中有一個responseType 的屬性。

XMLHttpRequest.responseType 屬性是一個枚舉值,返回響應的類型。允許作者將響應類型更改為arraybuffer, blob, document, json, 或 text 。

當然,這個值也不是瞎設的,當我們將 responseType 設置為一個特定的類型時,我們要確保服務器所返回的類型和你所設置的返回值類型是兼容的,不然的話,盡管有再多數據返回,也都成了 null。

responseType.png

我們再試:

success.png

終于成功了。

總結

涉及到二進制數據流操作的,我們使用Blob對象。

與服務端交互的,我們切記要設置responseType。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 十八歲的背影,十八歲的風景。 繪畫風格不限,期待大神們翻牌! 活動鏈接:你拍我畫2
    肥肥竹閱讀 535評論 6 2
  • 企鵝走起路來,一搖一晃,好像要摔倒,可他并不會摔倒。讓我們跟著企鵝看看他們要去哪里吧。 冰雪漸漸消融,溫暖的夏季到...
    LEO作者閱讀 867評論 0 2