之前暑假和團隊一起做了一個仿百度云盤的系統(tǒng)葫盼,涉及到文件的下載,預覽等等叠艳,都不需要攜帶token逆甜。想想其實這種設計是不合理的吁脱。但是當時由于技術水平不高来农,所以只能采取不加控制的文件操作崇猫。但是在新的任務中沪哺,給的接口就是要求headers中攜帶token曼玩,然后后臺返回文件流烘贴,折騰了一番終于80%上實現(xiàn)了這個功能羡儿。
- 首先講講不需要token驗證的文件下載前端怎么實現(xiàn)
原理其實非常簡單事示,利用a標簽
<a href="url" download="name"></a>
解釋一下早像,a標簽href里放置文件的地址,這個地址是文件在服務器上存儲的地址肖爵。
假如在服務器端有一個專門的文件服務器卢鹦,那么這個地址就是文件實際上在文件服務器中存儲的地址。
download其實可加可不加劝堪,表示文件的名稱冀自。不加就是文件的默認文件名
當點擊a標簽的時候揉稚,文件的下載過程,轉碼等等操作是由瀏覽器來自主完成的熬粗,瀏覽器能自動檢測文件擴展名來生成對應的文件格式搀玖。
- 然后講講需要token驗證的文件下載前端怎么做
首先是有兩種方法的
第一種,還是使用a標簽驻呐。在請求的正確返回里構造一個a標簽
this.$axios.get('/xxxxx')
.then(res => {
var btn = document.createElement("a");
btn .setAttribute('download', '');// download屬性
btn .setAttribute('href', '');// href鏈接
abtn click();// 自執(zhí)行點擊事件
})
由此可見巷怜,這種方法的關鍵在于,還是要后臺返回準確的文件地址
第二種的使用情景就是后臺返回的直接是文件流形式暴氏。js在瀏覽器環(huán)境中是不能像其他語言一樣對文件進行操作的(比如C的fread,java的讀取文件操作等等)延塑。
那么由于文件在網(wǎng)絡中傳輸都是以二進制流形式傳輸?shù)模晕覀円柚粋€特殊的對象=>Blob
Blob對象表示一個不可變的, 原始數(shù)據(jù)的類似文件對象答渔,blob對象本質上是js中的一個對象关带,里面可以儲存大量的二進制編碼格式的數(shù)據(jù)。實際上file類也是從blob類繼承來的沼撕。
下面演示一下如何用blob對象接收文件流宋雏。
this.$axios.get('XXXXXXX',{
responseType:'blob' //告訴服務器我們需要的響應格式
})
.then(res => {
let blob = new Blob([res.data],{
type:'application/vnd.ms-excel' //將會被放入到blob中的數(shù)組內容的MIME類型
});
let objectUrl = URL.createObjectURL(blob); //生成一個url
window.location.href = objectUrl; //瀏覽器打開這個url
})
.catch(err => {
console.log(err);
})
MIME類型 是設定某種擴展名的文件用一種應用程序來打開的方式類型,當該擴展名文件被訪問的時候务豺,瀏覽器會自動使用指定應用程序來打開
通過以上代碼磨总,我們就可以讓文件流被正確下載啦
最后來說說為什么我認為只實現(xiàn)了80%的期望功能。上述構造Blob對象的方式笼沥,生成的文件名是由Blob對象隨機生成的一段隨機數(shù)蚪燕,并不是期望的文件名。我暫時沒有找到在使用Blob的同時設置指定的文件名奔浅,希望大佬們多多指教