前言:本文詳細介紹在開發過程中前端如何與後端配合實現文件下載至本地,並詳細說明特殊格式文件如何處理。如果你是一名前端開發者,恰好需要實現後端文件下載至本地的需求,那麼恭喜你本篇文章一定會幫到你!
需求:實現二進制下載、URL下載、跨域下載
後端:Spring
前端:Vue
要點:後端返回文件流還是URL下載地址?
一、解析:二進制式下載
流程:後端返回二進制文件流的情況下,我們前端需要使用JS對象Blob構造函數來接收並儲存文件流,當服務器端發送完文件流之後,前端使用a標籤HTML5新屬性download屬性實現本地儲存,以達到實現下載需求。
後端返回內容:二進制文件流
前端做處理:
正常請求,後端給我們返回的是二進制流文件,由於前端需要使用Blob接受,所以在請求頭中需要告知服務器需要返回的數據類型,即 responseType: "blob",服務器返回的即是個blob對象。
思路:拿到Blob對象之後,使用URL.createObjectURL (前端API)生成一個可使用的URL地址,之後把這個URL地址賦給一個臨時創建的a標籤,當然我們的a標籤也需要download屬性纔可以擁有下載屬性
前端代碼:
this.$axios({
method: "post", //請求方式
responseType: "blob", //告訴服務器我們需要的響應格式
url: "fileService/fileService/download", //地址
data: {
fileId: item.fileId,
authorId: window.localStorage.getItem("authorId")
}
}).then(res => {
let url = window.URL.createObjectURL(new Blob([res.data])); //轉換爲可用URl地址
let link = document.createElement("a"); //創建a標籤
link.style.display = "none"; //使之不可見
link.href = url; //賦URL地址
link.setAttribute("download", item.fileName); //設置下載屬性、以及文件名
document.body.appendChild(link); //將a標籤插至頁面中
link.click(); //強制觸發a標籤事件
});
效果圖:
優點:適合1M以內的小文件下載
缺點:文件會在服務器端完全發送完畢之後、纔會展示出下載提示,用戶體驗感極差。
------二進制下載方式 完!------
二、解析:URL下載
流程:後端返回URL下載路徑,前端直接放置a標籤,並賦予a標籤download屬性,使其下載而不是直接打開。
後端返回內容:文件第三方下載地址
前端做處理:前端創建a標籤,賦予href爲文件下載地址即可
前端代碼:
Download() {
let link = document.createElement("a"); //創建a標籤
link.style.display = "none"; //使其隱藏
link.href = this.Data.filePath; //賦予文件下載地址
link.setAttribute("download", this.Data.fileName); //設置下載屬性 以及文件名
document.body.appendChild(link); //a標籤插至頁面中
link.click(); //強制觸發a標籤事件
},
效果:
優點:不限制文件大小
缺點:目測 無!
------URL下載方式 完!------
三、解析:跨域下載
表現:繼 ‘二’ 所述,在URL下載方式中,遇到mp4 / jpg / png等瀏覽器可以識別的文件格式時,下載提示框未彈出,直接在瀏覽器打開了該文件。
原因:經觀察是a標籤的download屬性失效。查閱一些資料後發現download屬性也受同源策略的影響,即非同一端口下不能直接下載第三方文件,所以這裏download失效之後做的僅僅是跳轉功能,類似於某一視頻下載地址直接通過瀏覽器get訪問跳轉。
效果圖:(未解決之前)
解決方式:後端 oss可以批量設置HTTP頭,設置HTTP請求頭爲Content-Disposition 爲 attachment即可,訪問的時候就是直接下載而不是瀏覽!
效果圖:(解決)
------ 全文 完!------
如果我的博客幫助你解決了開發問題,請不要吝嗇你的小紅心哦!❤