vue從后端獲取到文件的?url?地址及前端根據(jù)?url?地址下載文件的實現(xiàn)思路
前言
項目用的是 vben admin 框架,用的是 vue3 + TS
項目需求數(shù)據(jù)導出功能,前端需要實現(xiàn)文件下載功能
后端返回的是文件的 url 地址 (本項目中返回的是阿里云 oss 的文件地址)
一、實現(xiàn)思路
從后端得到的是一個 url 地址,先通過 fetch api 請求這個 url 地址并轉(zhuǎn)換成 blob 對象,通過 URL.createObjectUrl() 將 blob 對象生成 url 地址,綁定到 <a >
標簽 的 href 屬性上面,結(jié)合 download 來實現(xiàn)點擊 <a >
標簽下載文件
二、具體實現(xiàn)
1.完整代碼
代碼如下:
function exportData() { let data = getForm().getFieldsValue(); exportTowerHistoryToExcel({ deviceId, createTime: data.startTime }).then((url) => { downLoadFile(url); }); } function downLoadFile (url){ let fileName = url.slice(url.lastIndexOf('/') + 1); // 這里是通過從后端獲取到的 url 地址中截出來原本的文件名 fetch(url) .then((res) => res.blob()) .then((blob) => { const link = document.createElement('a'); link.href = URL.createObjectURL(blob); // 下載文件的名稱及文件類型后綴 link.download = fileName; document.body.appendChild(link); link.click(); //在資源下載完成后 清除 占用的緩存資源 window.URL.revokeObjectURL(link.href); document.body.removeChild(link); }); }
2.代碼分析
2.1 通過 fetch 將 url 地址轉(zhuǎn)換為 blob 對象
以下圖片來自w3cschool文檔 fetch_api
分析
res.blob() 的返回值是什么
從文檔中我們知道res.blob() 返回的并不是一個 blob 對象,而是一個 Promise,繼續(xù) .then 獲取到的才是 blob 對象
res.blob() 到底做了什么
每調(diào)用一次 res.blob() 都會執(zhí)行 consume budy
的動作
執(zhí)行流程大概是這個樣子 : 獲取字節(jié)流的讀取器 --> 通過讀取器來讀取到所有的數(shù)據(jù) --> 將數(shù)據(jù)包裝成 blob 對象并返回
2.2 通過 URL.createObjectUrl() 將 blob 對象生成 url 地址
以下圖片來自MDN文檔 URL.createObjectURL()
分析
URL.createObjURL() 做了什么
我們在調(diào)用 URL.createObjURL() 的時候傳遞的參數(shù)是一個 blob 對象,每次調(diào)用 URL.createObjURL() 的時候,都會創(chuàng)建一個新的 URL 對象
注意 : 即使是用同一個 blob 對象 , 每次調(diào)用 URL.createObjURL() 都會生成不同的 URL 對象
生成的的 URL 對象什么時候會被釋放
瀏覽器在 docoment 卸載的時候,會自動釋放
為了獲得最佳性能和內(nèi)存使用狀況,應當在不需要使用這些 URL 對象的安全的實際,主動釋放掉他們
怎么釋放生成的的 URL 對象
通過調(diào)用 URL.removeObjectURL(需要釋放的URL )
可以來釋放生成的 URL 對象
2.3 創(chuàng)建 <a> 標簽元素,將該元素放到頁面當中,并通過點擊事件來實現(xiàn)下載功能
<a href="xxxxx" rel="external nofollow" rel="external nofollow" > <a href="xxxxx" rel="external nofollow" rel="external nofollow" download="xxxx">
href:文件的絕對/相對地址
download: 文件名(可省略,省略后瀏覽器自動識別源文件名 , 但是有可能導致自動識別源文件名的時候沒有文件后綴,導致文件沒有格式)
const link = document.createElement('a'); link.href = URL.createObjectURL(blob); // 下載文件的名稱及文件類型后綴 link.download = fileName; // 這里 download 可以不寫 document.body.appendChild(link); link.click();
總結(jié)
其實找到這個解決方案的時候直接拿來用挺順利的,但是一開始并不明白它是怎么工作的,甚至每行都沒太明白它為什么這么做,在整理下來的過程中,反而理解了一些東西,與君共勉~
到此這篇關(guān)于vue 中從后端獲取到文件的 url 地址前端根據(jù) url 地址下載文件的文章就介紹到這了,更多相關(guān)vue后端獲取 url 地址內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解vue與后端數(shù)據(jù)交互(ajax):vue-resource
本篇文章主要介紹了詳解vue與后端數(shù)據(jù)交互(ajax):vue-resource,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03