Emberjs 通過(guò) axios 下載文件的方法
摘要: 目前項(xiàng)目中需要與后端合作,通過(guò)發(fā)送 GET 請(qǐng)求,后端返回文件流,前端進(jìn)行文件的下載。
使用到的技術(shù)有:
- Emberjs
- axios
思路
接到這個(gè)需求的話,想著使用創(chuàng)建 a 鏈接,然后模擬點(diǎn)擊 a 鏈接來(lái)完成下載,但是情況不是這樣的。后端有多于一個(gè)的下載接口,首先是生成下載文件的接口, 這個(gè)接口主要是返回 需要下載的文件的 name 以及相應(yīng)的接口地址。而下載的文件可能不止一個(gè),同時(shí),對(duì)文件接口地址發(fā)送 GET 請(qǐng)求,會(huì)返回文件流,但是我們需要的是 CSV 格式的文件,所以想到通過(guò) axios 來(lái)實(shí)現(xiàn)這個(gè)需求。
具體做法
既然方向確定了,那就是去做了。
在項(xiàng)目中安裝插件/導(dǎo)入 axios
現(xiàn)在 Emberjs 封裝好的 axios 插件 - ember-axios
,使用 ember install axios
。這個(gè)插件沒(méi)有文檔,所以只能看源碼,還好源碼比較簡(jiǎn)單,就是簡(jiǎn)單的將 axios 的一些方法封裝成一個(gè) service 內(nèi)的方法。
在項(xiàng)目文件中引入 axios
安裝后在 Emberjs 項(xiàng)目中將此 service 引入近來(lái)
import { inject as service } from '@ember/service'; export default Controller.extend({ // ... axios: service() // ... });
這樣即可使用這個(gè)插件中封裝的一些 axios 的方法。
使用
之前也說(shuō)過(guò)當(dāng)前項(xiàng)目需要先發(fā)送一個(gè)請(qǐng)求,請(qǐng)求文件的接口地址。返回的值的格式為:
{ "fileNames":[ "filename=downloadFile1.csv", "filename=downloadFile2.csv" ], "status":"ok" }
可以看到,如我們所想的那樣,返回的并不一定是單個(gè)文件的地址,所以我們?cè)诮邮盏竭@個(gè)數(shù)據(jù)后:
import { isEmpty } from '@ember/utils'; import { all, reject } from 'rsvp'; //... .then(data=> { if (data.status !== 'ok' || isEmpty(data.fileNames)) { return reject(); } return all(data.fileNames.map(ele => { return axios.axios({ url: `${ele}`, method: 'get', responseType: 'blob' }); })); });
在等待上面的請(qǐng)求發(fā)送成功之后,我們看看這段代碼的意思。最上面的兩個(gè) import 是引入的一些 Emberjs 中封裝的一些通用方法以及 promies 方法.在 then 之內(nèi)的代碼,先是驗(yàn)證是否返回成功。然后對(duì)數(shù)據(jù)進(jìn)行遍歷,并發(fā)送 axios 封裝的 get 請(qǐng)求。 其中 axios.axios()
是 ember-axios
封裝的 axios.create(this.config())
源碼地址 ,同時(shí)注意的是 config 對(duì)象中 responseType 填寫的是 blob ,這是保證文件能夠下載成功的基礎(chǔ)。
請(qǐng)求發(fā)送成功之后,我們需要對(duì)返回的數(shù)據(jù)進(jìn)行處理,也就是:
.then(data => { data.forEach((res, index) => { const content = res.data, blob = new Blob([content], { type: 'text/csv' }), fileName = fileNames[index]; if ('download' in document.createElement('a')) { // 非IE下載 const elink = document.createElement('a'); elink.download = fileName; elink.style.display = 'none'; elink.href = URL.createObjectURL(blob); document.body.appendChild(elink); elink.click(); URL.revokeObjectURL(elink.href); // 釋放URL 對(duì)象 document.body.removeChild(elink); } else { // IE10+下載 navigator.msSaveBlob(blob, fileName); } }); }).catch(() => { });
這段代碼需要注意的是我們 new Blob()
接收的是 res.data
這個(gè)需要特別注意。另外就是此方法的第二個(gè)參數(shù)接收的 {type: 'text/csv'}
,因?yàn)榇雾?xiàng)目下載的是 csv 文件格式,其他的可以參考 MIME . 其他的就是創(chuàng)建一個(gè) display:none
的 a 標(biāo)簽,并觸發(fā)點(diǎn)擊事件。這時(shí)候?yàn)g覽器就會(huì)進(jìn)行下載。
總結(jié)
這算是在 Embjerjs 中進(jìn)行下載流文件的一次船新嘗試。
以上所述是小編給大家介紹的Emberjs 通過(guò) axios 下載文件的方法,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
JavaScript Reflect Metadata實(shí)現(xiàn)詳解
這篇文章主要介紹了JavaScript Reflect Metadata實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12JavaScript實(shí)現(xiàn)文本目標(biāo)字符替換和一鍵全部替換
這篇文章主要介紹了JavaScript實(shí)現(xiàn)文本目標(biāo)字符替換和一鍵全部替換,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06Bootstrap基本樣式學(xué)習(xí)筆記之標(biāo)簽(5)
這篇文章主要介紹了Bootstrap學(xué)習(xí)筆記之標(biāo)簽基本樣式的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12Javascript獲取數(shù)組中的最大值和最小值的方法匯總
比較數(shù)組中數(shù)值的大小是比較常見的操作,下面同本文給大家分享四種放哪廣發(fā)獲取數(shù)組中最大值和最小值,對(duì)此感興趣的朋友一起學(xué)習(xí)吧2016-01-01通過(guò)BootStrap實(shí)現(xiàn)輪播圖的實(shí)際應(yīng)用
js我們沒(méi)有學(xué)過(guò),今天我是用bootstrap實(shí)現(xiàn)輪播圖的效果,非常不錯(cuò)代碼簡(jiǎn)單易懂,需要的朋友參考下吧2016-09-09javascript的parseFloat()方法精度問(wèn)題探討
javascript中的parseFloat()方法,大家應(yīng)該不陌生吧,下面為大家介紹下其精度問(wèn)題,感興趣的朋友不要錯(cuò)過(guò)2013-11-11