目錄
1.下載方法封裝
2.將后端返回的文件流轉換為文件
3.總結
1.下載方法封裝
①說明
前端的請求大概分為三種類型
普通請求:常用的get,post,put,delete等請求
上傳請求:使用post請求,發送formdata對象的參數,formdata中存放文件及其他參數
下載請求:使用post請求,設置響應格式為blob或者arraybuffer
②通用下載請求說明
api:
// 共通下載方法
export function dowload(url:string,params:any,filename:string,config:any) {return axios.post(url,params,{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },responseType: 'blob',...config}).then((data:any) =>{if(data.type !== 'application/json'){const blob = new Blob([data],{ type: 'application/vnd.ms-excel' })saveAs(blob,filename)// let objectUrl = URL.createObjectURL(blob) // 創建URL// let link = document.createElement("a");// link.href = objectUrl// link.download =filename // 自定義文件名// link.click() // 下載文件// URL.revokeObjectURL(objectUrl); // 釋放內存}}).catch((r:any) =>{console.log(r)Message.error({ content: '下載文件出現錯誤,請聯系管理員!', position: 'top' });})}
說明:
前端下載后端的文件,一般分為兩種類型,后端返回文件流或者后端將文件存儲在服務器,將地址返回至前端。
我使用的是后端返回文件流的方式,前端的請求需要將responseType設置為blob格式,代表后端返回的是二進制文件流。content-type按照需要進行設置,可以設置為application/x-www-form-urlencoded或者application/json,不同的方式決定了后端接收參數的方式不一樣。
攔截器設置:
axios.interceptors.response.use((response: AxiosResponse<any>) => {// 二進制數據則直接返回if (response.request.responseType === 'blob') {return response.data}const res = response.data;let resCode = res.resHdr?.resCode;let resMsg = res.resHdr?.resMsg || "請求未知異常";if (resCode == "9990_10" || resCode == "9990_9") {Message.error({content: "登錄信息過期,請重新登錄",duration: 5 * 1000,});// 跳轉登錄頁面router.push("/login");return Promise.reject(new Error(resMsg));}if (resCode !== "0000") {Message.error({content: resMsg,duration: 5 * 1000,});return Promise.reject(new Error(resMsg));}return res.resBody;},(error) => {Message.error({content: error.msg || "請求未知異常",duration: 5 * 1000,});return Promise.reject(error);}
);
說明:
響應攔截器中要對responseType進行判斷,如果是blob格式的,直接返回response中的data,其他格式時,一般為json,需要獲取返回的data的返回值進行判斷,登錄過期時跳轉到登錄畫面,并進行信息提示,異常時進行信息提示,正常時返回data,然后在接口中對data的內容進行處理。
2.將后端返回的文件流轉換為文件
在通過下載方法中,獲取到返回的data數據,需要將數據流轉為文件。
方式1:
// 共通下載方法
export function dowload(url:string,params:any,filename:string,config:any) {return axios.post(url,params,{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },responseType: 'blob',...config}).then((data:any) =>{if(data.type !== 'application/json'){const blob = new Blob([data],{ type: 'application/vnd.ms-excel' })let objectUrl = URL.createObjectURL(blob) // 創建URLlet link = document.createElement("a");link.href = objectUrllink.download =filename // 自定義文件名link.click() // 下載文件URL.revokeObjectURL(objectUrl); // 釋放內存}}).catch((r:any) =>{console.log(r)Message.error({ content: '下載文件出現錯誤,請聯系管理員!', position: 'top' });})}
?將data轉換為blob對象,然后根據blob創建url,再創建一個a元素,將a元素的href屬性和url進行綁定,再設置下載的文件名,觸發click事件進行下載。
方式2:
使用file-saver方式
①安裝依賴:
pnpm install file-saver --savepnpm install @types/file-saver --save-dev
②使用
import { saveAs } from 'file-saver'// 共通下載方法
export function dowload(url:string,params:any,filename:string,config:any) {return axios.post(url,params,{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },responseType: 'blob',...config}).then((data:any) =>{if(data.type !== 'application/json'){const blob = new Blob([data],{ type: 'application/vnd.ms-excel' })saveAs(blob,filename)}}).catch((r:any) =>{console.log(r)Message.error({ content: '下載文件出現錯誤,請聯系管理員!', position: 'top' });})}
?調用saveAs方式,傳遞blob對象及文件名即可
3.總結
注意通過下載方法的封裝
注意響應攔截器首先要對響應類型進行判斷,blob格式直接返回data
生成文件直接使用file-saver方式,比較方便