vue從后端獲取到文件的?url?地址及前端根據(jù)?url?地址下載文件的實(shí)現(xiàn)思路
前言
項(xiàng)目用的是 vben admin 框架,用的是 vue3 + TS
項(xiàng)目需求數(shù)據(jù)導(dǎo)出功能,前端需要實(shí)現(xiàn)文件下載功能
后端返回的是文件的 url 地址 (本項(xiàng)目中返回的是阿里云 oss 的文件地址)
一、實(shí)現(xiàn)思路
從后端得到的是一個(gè) url 地址,先通過(guò) fetch api 請(qǐng)求這個(gè) url 地址并轉(zhuǎn)換成 blob 對(duì)象,通過(guò) URL.createObjectUrl() 將 blob 對(duì)象生成 url 地址,綁定到 <a > 標(biāo)簽 的 href 屬性上面,結(jié)合 download 來(lái)實(shí)現(xiàn)點(diǎn)擊 <a > 標(biāo)簽下載文件
二、具體實(shí)現(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); // 這里是通過(guò)從后端獲取到的 url 地址中截出來(lái)原本的文件名
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 通過(guò) fetch 將 url 地址轉(zhuǎn)換為 blob 對(duì)象
以下圖片來(lái)自w3cschool文檔 fetch_api

分析
res.blob() 的返回值是什么
從文檔中我們知道res.blob() 返回的并不是一個(gè) blob 對(duì)象,而是一個(gè) Promise,繼續(xù) .then 獲取到的才是 blob 對(duì)象
res.blob() 到底做了什么
每調(diào)用一次 res.blob() 都會(huì)執(zhí)行 consume budy 的動(dòng)作
執(zhí)行流程大概是這個(gè)樣子 : 獲取字節(jié)流的讀取器 --> 通過(guò)讀取器來(lái)讀取到所有的數(shù)據(jù) --> 將數(shù)據(jù)包裝成 blob 對(duì)象并返回
2.2 通過(guò) URL.createObjectUrl() 將 blob 對(duì)象生成 url 地址
以下圖片來(lái)自MDN文檔 URL.createObjectURL()

分析
URL.createObjURL() 做了什么
我們?cè)谡{(diào)用 URL.createObjURL() 的時(shí)候傳遞的參數(shù)是一個(gè) blob 對(duì)象,每次調(diào)用 URL.createObjURL() 的時(shí)候,都會(huì)創(chuàng)建一個(gè)新的 URL 對(duì)象
注意 : 即使是用同一個(gè) blob 對(duì)象 , 每次調(diào)用 URL.createObjURL() 都會(huì)生成不同的 URL 對(duì)象
生成的的 URL 對(duì)象什么時(shí)候會(huì)被釋放
瀏覽器在 docoment 卸載的時(shí)候,會(huì)自動(dòng)釋放
為了獲得最佳性能和內(nèi)存使用狀況,應(yīng)當(dāng)在不需要使用這些 URL 對(duì)象的安全的實(shí)際,主動(dòng)釋放掉他們
怎么釋放生成的的 URL 對(duì)象
通過(guò)調(diào)用 URL.removeObjectURL(需要釋放的URL ) 可以來(lái)釋放生成的 URL 對(duì)象
2.3 創(chuàng)建 <a> 標(biāo)簽元素,將該元素放到頁(yè)面當(dāng)中,并通過(guò)點(diǎn)擊事件來(lái)實(shí)現(xiàn)下載功能
<a href="xxxxx" rel="external nofollow" rel="external nofollow" > <a href="xxxxx" rel="external nofollow" rel="external nofollow" download="xxxx">
href:文件的絕對(duì)/相對(duì)地址
download: 文件名(可省略,省略后瀏覽器自動(dòng)識(shí)別源文件名 , 但是有可能導(dǎo)致自動(dòng)識(shí)別源文件名的時(shí)候沒(méi)有文件后綴,導(dǎo)致文件沒(méi)有格式)
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
// 下載文件的名稱及文件類型后綴
link.download = fileName; // 這里 download 可以不寫
document.body.appendChild(link);
link.click();總結(jié)
其實(shí)找到這個(gè)解決方案的時(shí)候直接拿來(lái)用挺順利的,但是一開始并不明白它是怎么工作的,甚至每行都沒(méi)太明白它為什么這么做,在整理下來(lái)的過(guò)程中,反而理解了一些東西,與君共勉~
到此這篇關(guān)于vue 中從后端獲取到文件的 url 地址前端根據(jù) url 地址下載文件的文章就介紹到這了,更多相關(guān)vue后端獲取 url 地址內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解vue與后端數(shù)據(jù)交互(ajax):vue-resource
本篇文章主要介紹了詳解vue與后端數(shù)據(jù)交互(ajax):vue-resource,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03
一文詳解Vue選項(xiàng)式?API?的生命周期選項(xiàng)和組合式API
這篇文章主要為大家介紹了Vue選項(xiàng)式?API?的生命周期選項(xiàng)和組合式API變化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
對(duì)vue下點(diǎn)擊事件傳參和不傳參的區(qū)別詳解
今天小編就為大家分享一篇對(duì)vue下點(diǎn)擊事件傳參和不傳參的區(qū)別詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
vue項(xiàng)目中使用rem,在入口文件添加內(nèi)容操作
這篇文章主要介紹了vue項(xiàng)目中使用rem,在入口文件添加內(nèi)容操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11

