前端實(shí)現(xiàn)獲取后端返回的文件流并下載三種方法
在前端開(kāi)發(fā)中,有時(shí)需要從后端獲取文件流,并將其下載到本地。本文介紹如何在前端實(shí)現(xiàn)此功能的不同的實(shí)現(xiàn)方法,并分析其優(yōu)缺點(diǎn)
方法一:使用Axios實(shí)現(xiàn)文件流下載
使用Axios實(shí)現(xiàn)文件流下載的方法,本人親測(cè)可以實(shí)現(xiàn)
import axios from 'axios'; import { getToken } from '@/utils/auth' handleExport() { // 接口調(diào)用獲取文件 axios({ method: 'get', responseType: 'blob', // 指定響應(yīng)類(lèi)型為blob url: this.GLOBAL.baseURL + '/api/v1/business/user/export', data: this.queryParams, // 導(dǎo)入文件一般都用FormData格式數(shù)據(jù) headers: { 'Authorization': 'Bearer ' + getToken() } // 傳遞token進(jìn)行身份驗(yàn)證 }).then(res => { if (res.code === 200) { // 導(dǎo)入成功 this.downloadBinaryFile(res.data, '導(dǎo)入失敗后下載的報(bào)錯(cuò)文件') } else { // 輸出失敗信息 } }).catch(error => { console.error('下載失敗', error); }); }, /** * 將二進(jìn)制文件下載到本地,保存為excel文件 * @param {*} binFile 二進(jìn)制文件流 * @param {*} fileName 下載后的文件名 * @param {*} blobType 文件格式,默認(rèn)為 "application/vnd.ms-excel" */ downloadBinaryFile(binFile, fileName, blobType = "application/vnd.ms-excel") { // 創(chuàng)建 Blob 對(duì)象,包含二進(jìn)制文件流和文件類(lèi)型 const blobObj = new Blob([binFile], { type: blobType }); // 創(chuàng)建下載鏈接元素 const downloadLink = document.createElement('a'); // 處理不同瀏覽器的 URL 兼容性 let url = window.URL || window.webkitURL; url = url.createObjectURL(blobObj); // 創(chuàng)建文件 URL // 設(shè)置下載鏈接屬性 downloadLink.href = url; downloadLink.download = fileName; // 將下載鏈接添加到文檔中并觸發(fā)點(diǎn)擊事件 document.body.appendChild(downloadLink); downloadLink.click(); // 移除下載鏈接并釋放 URL 對(duì)象 document.body.removeChild(downloadLink); window.URL.revokeObjectURL(url); }
實(shí)現(xiàn)的效果
優(yōu)點(diǎn)
- 支持傳遞Token進(jìn)行身份驗(yàn)證,安全性較高
- 支持POST請(qǐng)求,可以將參數(shù)放在請(qǐng)求體中,避免URL長(zhǎng)度限制及參數(shù)暴露
缺點(diǎn)
- 實(shí)現(xiàn)相對(duì)復(fù)雜,需要手動(dòng)創(chuàng)建和管理Blob對(duì)象及下載鏈接
方法二:使用封裝的Request工具實(shí)現(xiàn)文件流下載
接下來(lái)介紹使用封裝的Request工具實(shí)現(xiàn)文件流下載的方法
import request from '@/utils/request' // 日志管理收藏、瀏覽、下載導(dǎo)出接口 export function exportUserOperateAdmin(data, headers) { return request({ url: '/business/user/export', method: 'get', data: data, headers: headers }) } // 調(diào)用導(dǎo)出接口 exportUserOperateAdmin(this.queryParams, { responseType: 'blob' }).then( response => { console.log(response) const url = window.URL.createObjectURL(new Blob([response.data])) // 創(chuàng)建下載鏈接 const link = document.createElement('a') link.href = url link.download = '全文導(dǎo)入模板.xlsx' // 設(shè)置文件名 document.body.appendChild(link) link.click() // 觸發(fā)下載 document.body.removeChild(link) // 下載后移除元素 } ).catch(error => { console.error('下載失敗', error) this.loading = false // 停止加載,隱藏加載狀態(tài) })
優(yōu)點(diǎn)
- 封裝后的Request工具調(diào)用簡(jiǎn)單,代碼更簡(jiǎn)潔
- 支持傳遞Token進(jìn)行身份驗(yàn)證,安全性較高
缺點(diǎn)
- 實(shí)現(xiàn)相對(duì)簡(jiǎn)單,但仍需手動(dòng)處理Blob對(duì)象及下載鏈接
方法三:直接通過(guò)URL跳轉(zhuǎn)下載
最后介紹直接通過(guò)URL跳轉(zhuǎn)實(shí)現(xiàn)文件下載的方法
const baseurl = this.GLOBAL.baseURL // 拼接上導(dǎo)出的地址,如果接口還需要其他參數(shù),都可以直接拼接上 let url = baseurl + '/api/v1/business/user/export'; console.log(url) alert(url) // 第二個(gè)參數(shù)'_self'表示在當(dāng)前頁(yè)下載,不打開(kāi)新的頁(yè)面 window.open(url, '_self')
優(yōu)點(diǎn)
- 實(shí)現(xiàn)簡(jiǎn)單,不需要處理Blob對(duì)象及下載鏈接
- 適合下載無(wú)需身份驗(yàn)證或參數(shù)簡(jiǎn)單的文件
缺點(diǎn)
- 無(wú)法傳遞Token進(jìn)行身份驗(yàn)證,安全性較低
- 參數(shù)放在URL中不安全,且可能會(huì)導(dǎo)致URL過(guò)長(zhǎng)
- 處理中文參數(shù)可能會(huì)出現(xiàn)亂碼問(wèn)題
結(jié)論
以上三種方法各有優(yōu)缺點(diǎn),實(shí)際開(kāi)發(fā)中可以根據(jù)具體需求選擇合適的方法。
如果需要傳遞Token進(jìn)行身份驗(yàn)證并確保下載安全性,推薦使用方法一或方法二
如果只是簡(jiǎn)單下載無(wú)需驗(yàn)證的文件,可以考慮使用方法三
到此這篇關(guān)于前端實(shí)現(xiàn)獲取后端返回的文件流并下載三種方法的文章就介紹到這了,更多相關(guān)前端獲取后端返回文件流下載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)盒子滾動(dòng)動(dòng)畫(huà)效果
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)盒子滾動(dòng)動(dòng)畫(huà)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08淺談對(duì)于“不用setInterval,用setTimeout”的理解
這篇文章主要介紹了淺談對(duì)于“不用setInterval,用setTimeout”的理解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08javascript與CSS復(fù)習(xí)(《精通javascript》)
js和css結(jié)合來(lái)產(chǎn)生醒目的交互效果,我們可以快速的訪(fǎng)問(wèn)元素自身的樣式屬性2010-06-06JavaScript中l(wèi)ayim之整合右鍵菜單的示例代碼
這篇文章主要介紹了JavaScript中l(wèi)ayim之整合右鍵菜單的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02點(diǎn)擊按鈕出現(xiàn)60秒倒計(jì)時(shí)的簡(jiǎn)單js代碼(推薦)
下面小編就為大家?guī)?lái)一篇點(diǎn)擊按鈕出現(xiàn)60秒倒計(jì)時(shí)的簡(jiǎn)單js代碼(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06詳解webpack 配合babel 將es6轉(zhuǎn)成es5 超簡(jiǎn)單實(shí)例
本篇文章主要介紹了詳解webpack 配合babel 將es6轉(zhuǎn)成es5 超簡(jiǎn)單實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05JavaScript 聯(lián)動(dòng)的無(wú)限級(jí)封裝類(lèi),數(shù)據(jù)采用非Ajax方式,隨意添加聯(lián)動(dòng)
JavaScript 聯(lián)動(dòng)的無(wú)限級(jí)封裝類(lèi),數(shù)據(jù)采用非Ajax方式,隨意添加聯(lián)動(dòng)2010-06-06javascript 獲取radio的value的函數(shù) [已測(cè)]
javascript 獲取radio的value的函數(shù) 如果與asp,php等后臺(tái)語(yǔ)言結(jié)合時(shí),一般用不到,但在純js環(huán)境下是必須的。2009-06-06