后端返回了 xlsx 文件流,前端怎么下載處理

當后端返回一個 .xlsx 文件流時,前端可以通過 JavaScript 處理這個文件流并觸發瀏覽器下載。


實現步驟

  1. 發送請求獲取文件流
    使用 fetchaxios 等工具向后端發送請求,確保響應類型設置為 blob(二進制數據流)。

  2. 創建 Blob 對象
    將返回的文件流轉換為 Blob 對象,這是處理二進制數據的標準方式。

  3. 生成下載鏈接
    使用 URL.createObjectURL 方法將 Blob 對象轉換為一個臨時 URL。

  4. 觸發下載
    動態創建一個 <a> 標簽,設置其 href 屬性為生成的臨時 URL,并調用 click() 方法觸發下載。

  5. 清理資源
    下載完成后,使用 URL.revokeObjectURL 釋放生成的臨時 URL,避免內存泄漏。


使用 axios 實現

如果你使用的是 axios,可以這樣實現:

import axios from 'axios';const downloadXlsx = async () => {try {// 發送請求并獲取文件流const response = await axios.get('/api/download-xlsx', {responseType: 'blob', // 確保響應類型為 blobheaders: {'Authorization': 'Bearer your_token_here', // 如果需要攜帶認證信息},});// 創建 Blob 對象const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });// 創建臨時 URLconst url = window.URL.createObjectURL(blob);// 創建 <a> 標簽并觸發下載const a = document.createElement('a');a.href = url;a.download = 'example.xlsx'; // 設置下載文件名document.body.appendChild(a); // 將 <a> 添加到 DOM 中(可選)a.click(); // 觸發點擊事件// 清理資源window.URL.revokeObjectURL(url);a.remove(); // 移除 <a> 標簽} catch (error) {console.error('下載文件時發生錯誤:', error.message || '未知錯誤');}
};// 調用函數
downloadXlsx();
responseType: 'blob'?的含義
  • responseType?是 Axios 提供的一個配置選項,用于告訴 Axios 如何解析服務器返回的數據。
  • 當設置為?'blob'?時,表示你期望服務器返回的數據是一個二進制大對象(Binary Large Object,簡稱 Blob)。
Blob 是什么?
  • Blob?是一種數據類型,通常用來表示不可變的、原始數據的類文件對象。
  • 它可以包含文本、圖像、音頻、視頻等二進制數據,或者混合內容。
  • 在前端開發中,Blob 常用于處理文件下載、圖片預覽、或者將數據保存為文件。
為什么需要?responseType: 'blob'

當從服務器請求文件(如 Excel 文件、PDF 文件、圖片等)時,服務器通常會返回二進制數據。如果直接使用默認的 responseType(通常是 'json'),Axios 會嘗試將響應數據解析為 JSON 格式,這會導致錯誤或數據損壞。

通過設置 responseType: 'blob',你可以確保 Axios 正確地將響應數據作為二進制數據處理,而不會嘗試將其解析為其他格式(如 JSON 或文本)。

代碼的作用
const response = await axios({url: '/api/download-xlsx',method: 'GET',responseType: 'blob', // 指定響應數據為 Blob 類型
});
  1. 發起 GET 請求

    • 向?/api/download-xlsx?發起一個 GET 請求,通常用于下載文件(例如 Excel 文件)。
  2. 指定響應類型

    • 設置?responseType: 'blob',告訴 Axios 將服務器返回的數據解析為 Blob 對象。
  3. 處理響應數據

    • 返回的?response.data?將是一個 Blob 對象,代表下載的文件內容。

使用 fetch 實現

const downloadXlsx = async () => {try {// 發送請求并獲取文件流const response = await fetch('/api/download-xlsx', {method: 'GET',headers: {'Authorization': 'Bearer your_token_here', // 如果需要攜帶認證信息},});// 檢查響應是否成功if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}// 獲取 blob 數據const blob = await response.blob();// 創建臨時 URLconst url = window.URL.createObjectURL(blob);// 創建 <a> 標簽并觸發下載const a = document.createElement('a');a.href = url;a.download = 'example.xlsx'; // 設置下載文件名document.body.appendChild(a); // 將 <a> 添加到 DOM 中(可選)a.click(); // 觸發點擊事件// 清理資源window.URL.revokeObjectURL(url);a.remove(); // 移除 <a> 標簽} catch (error) {console.error('下載文件時發生錯誤:', error.message || '未知錯誤');}
};// 調用函數
downloadXlsx();
1. 定義異步函數
javascript
深色版本
const downloadXlsx = async () => {
  • async?關鍵字表示這是一個異步函數。
  • 異步函數允許使用?await?來等待異步操作(如網絡請求)完成。

2. 發起 HTTP 請求
const response = await fetch('/api/download-xlsx', {method: 'GET',headers: {'Authorization': 'Bearer your_token_here', // 如果需要攜帶認證信息},
});
  • 使用?fetch?發起一個 GET 請求到?/api/download-xlsx

  • headers?部分用于設置請求頭:

    • 'Authorization'?是一個常見的請求頭字段,用于傳遞用戶的身份驗證信息(如 JWT Token)。
    • 如果 API 不需要認證,可以省略?headers

3. 檢查響應狀態
if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);
}
  • response.ok?是一個布爾值,表示 HTTP 響應的狀態碼是否在 200-299 范圍內。
  • 如果響應失敗(如 404 或 500 錯誤),會拋出一個錯誤,并終止后續代碼執行。
  • 拋出的錯誤會被?catch?塊捕獲。

4. 獲取 Blob 數據
const blob = await response.blob();
  • response.blob() ?將響應數據解析為一個?Blob?對象。
  • Blob?是一種二進制數據類型,通常用來表示文件內容。
  • await?確保在繼續執行后續代碼之前,blob?數據已經被完全加載。

5. 創建臨時 URL
const url = window.URL.createObjectURL(blob);
  • window.URL.createObjectURL(blob) ?創建一個指向?Blob?的臨時 URL。
  • 這個 URL 可以被用作?<a>?標簽的?href?屬性,從而觸發文件下載。

6. 創建?<a>?標簽并觸發下載
const a = document.createElement('a');
a.href = url;
a.download = 'example.xlsx'; // 設置下載文件名
document.body.appendChild(a); // 將 <a> 添加到 DOM 中(可選)
a.click(); // 觸發點擊事件
  • 創建?<a>?標簽

    • 使用?document.createElement('a')?動態創建一個?<a>?元素。
  • 設置?<a>?標簽屬性

    • href:設置為前面生成的臨時 URL。
    • download:指定下載文件的名稱(如?example.xlsx)。
  • 添加到 DOM 并觸發點擊

    • 將?<a>?標簽添加到文檔中(雖然不是必須,但某些瀏覽器可能需要這樣做)。
    • 使用?a.click()?模擬用戶點擊,從而觸發文件下載。

7. 清理資源
window.URL.revokeObjectURL(url);
a.remove();
  • 釋放臨時 URL

    • 使用?window.URL.revokeObjectURL(url)?釋放前面創建的臨時 URL,避免內存泄漏。
  • 移除?<a>?標簽

    • 使用?a.remove()?從 DOM 中移除?<a>?標簽,保持頁面整潔。

8. 錯誤處理
} catch (error) {console.error('下載文件時發生錯誤:', error.message || '未知錯誤');
}
  • catch?塊?用于捕獲和處理可能出現的錯誤。
  • 如果在?try?塊中的任何一步發生錯誤(如網絡問題、API 返回錯誤等),都會進入?catch?塊。
  • 使用?console.error?打印錯誤信息,方便調試。

9. 調用函數
downloadXlsx();
  • 最后調用?downloadXlsx?函數,觸發整個文件下載流程。
適用場景
  • 下載動態生成的文件(如 Excel 表格、PDF 文檔等)。
  • 需要通過 API 獲取文件內容并提供給用戶下載的場景。
注意事項
  1. 跨域問題

    • 如果 API 存在跨域限制,需要確保服務器配置了正確的 CORS(跨域資源共享)策略。
  2. 大文件下載

    • 對于非常大的文件,可能需要考慮分塊下載或流式處理,以避免內存占用過高。
  3. 瀏覽器兼容性

    • fetch?和?Blob?在現代瀏覽器中廣泛支持,但在一些老舊瀏覽器中可能需要使用?XMLHttpRequest?替代。

關鍵點說明

  1. 設置正確的 MIME 類型

    • .xlsx 文件的 MIME 類型是 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    • 如果后端未正確設置 MIME 類型,前端可以通過 Blob 的第二個參數手動指定。
  2. 動態文件名

    • 如果后端在響應頭中提供了文件名(例如通過 Content-Disposition),可以通過解析響應頭來動態設置文件名。
    • 示例:
      const contentDisposition = response.headers['content-disposition'];
      let fileName = 'example.xlsx';
      if (contentDisposition && contentDisposition.includes('filename=')) {fileName = contentDisposition.split('filename=')[1].split(';')[0];
      }
      
  3. 錯誤處理

    • 在實際開發中,務必對請求錯誤進行處理,例如檢查 HTTP 狀態碼是否為 200,或者捕獲網絡異常。
  4. 兼容性

    • 上述方法適用于現代瀏覽器(如 Chrome、Firefox、Edge、Safari)。如果需要支持舊版瀏覽器,可能需要引入 FileSaver.js 庫。

使用 FileSaver.js 簡化操作

如果你希望簡化文件下載邏輯,可以使用第三方庫 file-saver。安裝后,只需幾行代碼即可完成下載。

安裝
npm install file-saver
使用示例
import { saveAs } from 'file-saver';
import axios from 'axios';const downloadXlsx = async () => {try {const response = await axios({url: '/api/download-xlsx',method: 'GET',responseType: 'blob',});// 使用 FileSaver.js 保存文件saveAs(response.data, 'example.xlsx');} catch (error) {console.error('下載失敗:', error);}
};// 調用函數
downloadXlsx();

總結

  • 核心步驟:獲取文件流 -> 轉換為 Blob -> 創建臨時 URL -> 觸發下載 -> 清理資源。
  • 推薦工具fetchaxios 可以輕松獲取文件流,FileSaver.js 可以進一步簡化代碼。
  • 注意事項:確保后端返回的文件流格式正確,前端設置合適的 MIME 類型和文件名。

axios 處理

try {const response = await axios({url: '/api/download-xlsx',method: 'GET',responseType: 'blob', // 一定要注意請求時加此方法});getExportListApi(exportCarryData).then((res) => {// 創建一個a標簽const link = document.createElement('a');const url = window.URL.create0bjectURL(new Blob([res.data])); link.href = url;link.setAttribute('download', exportfile);document.body.appendChild(link); link.click();// 銷毀a標簽document.body.removeChild(link); window.URL.revoke0bjectURL(url);message.success('導出成功!');}); 

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74505.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74505.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74505.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

HTML5拖拽功能教程

HTML5拖拽功能教程 簡介 HTML5引入了原生拖放(Drag and Drop)API&#xff0c;使開發者能夠輕松實現網頁中的拖拽功能&#xff0c;無需依賴第三方庫。拖拽功能可以大大提升用戶體驗&#xff0c;適用于文件上傳、列表排序、看板系統等多種交互場景。本教程將帶您全面了解HTML拖…

VUE3 路由配置

1.下載 VueRouter 模塊 在命令行中輸入 yarn add vue-router 2.導?相關函數 在自己創建的router/index.js 文件中 import { createRouter, createWebHashHistory } from vue-router 3.創建路由實例 在自己創建的router/index.js 文件中 const theFirstRouter ()>{return…

歷史序列影像 Esri的World Imagery Wayback簡介

Esri的World Imagery Wayback是一個專注于提供歷史衛星影像的在線平臺&#xff0c;由全球領先的地理信息系統&#xff08;GIS&#xff09;技術提供商Esri開發。該平臺整合了多源衛星影像數據&#xff0c;允許用戶回溯特定區域在不同時間點的影像變化&#xff0c;支持時間序列分…

golang結構體與指針類型

結構體與指針類型 指針類型字段 具名字段 舉例 package struct_knowledgeimport "fmt"//結構體字段為指針類型 func StructWithPoint(){type Student struct{name *string}var lisa Studentfmt.Printf("賦值前,Student的實例的值%#v\n",lisa)//錯誤的賦…

NetMizer-日志管理系統-遠程命令執行漏洞挖掘

漏洞描述&#xff1a;NetMizer 日志管理系統 cmd.php中存在遠程命令執行漏洞&#xff0c;攻擊者通過傳入 cmd參數即可命令執行 1.fofa搜素語句 title"NetMizer 日志管理系統" 2.漏洞驗證 網站頁面 驗證POC /data/manage/cmd.php?cmdid

Contactile三軸觸覺傳感器:多維力感賦能機器人抓取

在非結構化環境中&#xff0c;機器人對物體的精準抓取與操作始終面臨巨大挑戰。傳統傳感器因無法全面感知觸覺參數&#xff08;如三維力、位移、摩擦&#xff09;&#xff0c;難以適應復雜多變的場景。Contactile推出的三軸觸覺力傳感器&#xff0c;通過仿生設計與創新光學技術…

OpenCV三維解算常用方法C++

如果標定過程是通過OpenCV張正友標定法實現的&#xff0c;得到的內參外參保存在.txt文件中是這樣的形式&#xff1a; ① 內參intrinsics.txt&#xff1a; ② 外參extrinsics.txt&#xff1a; 那么可以通過如下方法讀取.txt文件獲取左右相機內外參&#xff0c;主要包括三維解算…

棧和隊列相關知識題目

棧的底層原理 棧&#xff08;Stack&#xff09;是一種后進先出&#xff08;LIFO&#xff09;?的線性數據結構&#xff0c;所有操作&#xff08;如插入、刪除&#xff09;僅在棧頂進行。它的底層實現可以是數組或鏈表&#xff0c;具體取決于編程語言和應用場景。 1.基于數組實…

【實戰案例】永洪vividime:精準賦能零售行業,實現數據洞察與業務增長

在零售食品行業變革加速、市場競爭白熱化的背景下&#xff0c;XX集團作為休閑食品領域頭部企業&#xff0c;面臨消費趨勢變化、宏觀經濟承壓及業績增長乏力的多重挑戰。為破解增長困境&#xff0c;集團將“收入增長金額”確立為核心戰略指標&#xff08;北極星指標&#xff09;…

一些題目記錄

別人面經題目記錄 https://zhuanlan.zhihu.com/p/32626732052 實現 NMS&#xff0c;七八次&#xff0c;很高頻&#xff1b; 實現 MultiHeadSelfAttention&#xff0c;大概 三四次&#xff1b; 用 Numpy 或者 List 實現MLP 的前向和反向&#xff0c;4次&#xff1b; Leetcode …

面試題分享-多線程順序打印奇偶數

目錄 1.題目詳情 2.解題思路 2.1.分析題目 2.2.解析思路 3.代碼實現 4.運行結果 1.題目詳情 昨天刷抖音&#xff0c;遇到一個面試題&#xff0c;描述如下&#xff1a; 請使用兩個線程&#xff0c;分別順序交替打印奇數和偶數&#xff0c;直到10為止。例如有兩個線程&#…

模型 杜根定律

系列文章分享模型&#xff0c;了解更多&#x1f449; 模型_思維模型目錄。信心>能力、行動導向、未來時態。 1 杜根定律的應用 1.1 公共政策博弈——底特律市長杜根的保險改革攻堅戰 核心挑戰&#xff1a;底特律市長Mike Duggan面臨汽車保險費率畸高導致居民陷入貧困循環的…

關于在vscode中的Linux 0.11 應用程序項目的生成和運行

首先我們需要需要查看鏡像文件 查看軟盤鏡像文件 floppyb.img 中的內容 在 VSCode 的“Terminal”菜單中選擇“Run Build Task...”&#xff0c;會在 VSCode 的頂部中間位置彈出一個 可以執行的 Task 列表&#xff0c;選擇其中的“打開 floppyb.img”后會使用 Floppy Editor …

使用CSS3實現炫酷的3D視差滾動效果

使用CSS3實現炫酷的3D視差滾動效果 這里寫目錄標題 使用CSS3實現炫酷的3D視差滾動效果項目概述核心技術實現1. 3D空間的創建2. 視差層級設置3. 動畫效果實現流星動畫月亮發光效果 技術難點與解決方案1. 層級重疊問題2. 性能優化3. 響應式適配 開發心得總結 項目概述 在這個項目…

作業12 (2023-05-15 指針概念)

第1題/共11題【單選題】 關于指針的概念,錯誤的是:( ) A.指針變量是用來存放地址的變量 B.指針變量中存的有效地址可以唯一指向內存中的一塊區域 C.野指針也可以正常使用 D.局部指針變量不初始化就是野指針 回答正確 答案解析: A:正確,指針變量中存儲的是一個地址,指…

【ESP32S3】esp32獲取串口數據并通過http上傳到前端

通過前面的學習&#xff08;前面沒發過&#xff0c;因為其實就是跑它的demo&#xff09;了解到串口配置以及開啟線程實現功能的工作流程&#xff0c;與此同時還有esp32作為STA節點&#xff0c;將數據通過http發送到服務器。 將這兩者聯合 其實是可以得到一個&#xff1a;esp32獲…

《鴻蒙攜手AI:解鎖智慧出行底層邏輯》

在科技飛速發展的當下&#xff0c;智慧出行成為人們對未來交通的美好期許&#xff0c;而鴻蒙系統與人工智能的深度融合&#xff0c;正為這一愿景的實現提供強大助力。從技術原理角度深入剖析&#xff0c;鴻蒙系統究竟如何支撐人工智能在智慧出行場景中的應用呢&#xff1f;這背…

MyBatis-Plus緩存機制深度解析與SpringBoot整合實戰

一、MyBatis-Plus緩存機制全景解析 MyBatis-Plus在MyBatis原生緩存基礎上進行了深度增強,形成了多層次的緩存體系: 1. 緩存層級架構 應用層 ├── MP擴展緩存(多租戶/邏輯刪除) ├── 二級緩存(Mapper級別,跨Session共享) └── 一級緩存(SqlSession級別,默認開…

Day38 | 1365. 有多少小于當前數字的數字、941. 有效的山脈數組、1207. 獨一無二的出現次數、283. 移動零、189. 輪轉數組

1365. 有多少小于當前數字的數字 題目鏈接&#xff1a;1365. 有多少小、于當前數字的數字 - 力扣&#xff08;LeetCode&#xff09; 題目難度&#xff1a;簡單 代碼&#xff1a; class Solution {public int[] smallerNumbersThanCurrent(int[] nums) {Map<Integer,Inte…

數據人的進階之路:四年數倉實踐與成長思考

前言 在數據倉庫開發的過程中&#xff0c;常常會遇到很多值得思考的問題&#xff0c;它們不僅關乎技術的深度&#xff0c;也涉及業務理解、個人的成長&#xff0c;甚至是數據行業未來的價值。回顧過去的經歷&#xff0c;有很多問題反復出現&#xff0c;甚至成為繞不開的課題&am…