前端獲取后端文件流下載excel,pdf,word等文件

今天工作碰到一個需求,點擊按鈕導出excel,后端是直接返回的文件流,如下圖:


后端返回的文件流

方案一

直接用a標簽來改造這個按鈕,把下載地址放到href里,因為后端已經在響應頭里設置了文件名和文件類型,點擊按鈕就能下載帶有默認文件名的excel文件了。但是這個方案中,地址如果是動態的就不夠靈活了。


響應頭

方案二

按鈕不變成a標簽,在按鈕的點擊事件里處理

// 獲取baseurl
click(){
    const baseurl= `xxx`;
    // 拼接上導出的地址,如果接口還需要其他參數,都可以直接拼接上
    let url=`${baseurl}/xxx/export/${xxx}`
    // 第二個參數'_self'表示在當前頁下載,不打開新的頁面
    window.open(url,'_self')
}

方案三

直接處理文件流

axios({
  method: '請求方法(get/post)',
  url: '地址',
  data: '請求參數',
  responseType: 'blob' // 響應數據的類型要設置成blob,設置arraybuffer也可以,下文有解釋
}).then((res) => {
  // 解析文件名
  const str = res.headers['content-disposition'].split(';')[1].split('=')[1];
  const filename = decodeURIComponent(str);
  // 用blob存儲二進制文件
  const blob = new Blob([res.data], {
    type: 'application/vnd.ms-excel', // 設置文件類型 pdf是application/pdf,word是application/vnd.openxmlformats-officedocument.wordprocessingml.document,其他類型可以百度一下
  });
  // 創建一個臨時的url指向blob對象
  const objectUrl = window.URL.createObjectURL(blob);
  // 創建url之后可以模擬對此文件對象的一系列操作,例如:預覽、下載
  const a = document.createElement('a');
  a.setAttribute('href', objectUrl);
  a.setAttribute('download', filename);
  a.click();
  // 5.釋放這個臨時的對象url
  window.URL.revokeObjectURL(objectUrl);
}).catch(error => {
  ...
});

Blob(Binary Large Object)是用于表示大型二進制數據對象的 JavaScript 數據類型。它是一個不可變的原始數據對象,可以存儲各種類型的數據,如圖像、音頻、視頻和其他任意二進制數據。
Blob 對象和 ArrayBuffer 對象在某些方面相似,因為它們都可以用來存儲二進制數據。但是,它們之間也存在一些重要的區別。
數據存儲形式:ArrayBuffer 是一個連續的、固定長度的原始二進制數據緩沖區。它是在內存中分配一塊指定長度的空間來存儲數據。而 Blob 是一個非連續的二進制數據對象,它可以由多個片段(即 Blob 的數據塊)組成。這意味著 Blob 對象可以由不同的數據來源進行構建,例如從文件、網絡請求或其他 Blob 對象中創建。
可訪問性:ArrayBuffer 對象提供了一種機制,通過 TypedArray 和 DataView 視圖來直接讀取和修改數據。而 Blob 對象并不直接暴露數據的內容,而是提供了一組異步方法(例如 FileReader)來讀取其中的數據。
用途和應用場景:ArrayBuffer 主要用于在 JavaScript 中高效地處理和操作二進制數據,例如圖像處理、音頻解碼、加密算法等。而 Blob 對象更適合用于處理文件、上傳下載、數據傳輸等場景,因為它可以方便地保存和傳遞整個數據塊,而不需要直接讀取或修改其內容。
總結一下,ArrayBuffer 和 Blob 都是用于處理二進制數據的 JavaScript 數據類型。ArrayBuffer 是一個連續的固定長度二進制數據緩沖區,而 Blob 是一個非連續的二進制數據對象,可以由多個片段組成。ArrayBuffer 提供了直接讀取和修改數據的能力,而 Blob 則適用于處理文件、上傳下載和數據傳輸等場景。根據具體的使用需求,選擇使用適合的數據類型來操作和處理二進制數據。

補充

最近開發時,和新的后端同學聯調時發現要么下載的文件打不開,要么下載的文件是空白,研究了一下發現是后端代碼少配置了幾個屬性,Access-Control-Expose-Headers這個響應頭的屬性需要設置前端可見,Content-Type要設置成對應的文件類型,Content-Disposition數據處理方式和文件名也要處理一下。
下面代碼是我用koa寫的后端獲取文件流示例代碼,安裝koa和koa2-cors的依賴后,把需要給前端的文件地址配置一下,就可以node index.js運行了,給前端的url就是http://localhost:3000

文件名:index.js
const Koa = require('koa');
const cors = require('koa2-cors');
const fs = require('fs');
const path = require('path');
const app = new Koa();

app.use(cors());

// 讓Content-Disposition在前端可見,需要設置Access-Control-Expose-Headers
app.use(async (ctx, next) => {
  ctx.set('Access-Control-Expose-Headers', 'Content-Disposition');
  await next();
});

app.use(async ctx => {
    // 獲取文件路徑
    const filePath = path.join(__dirname, './jianli.pdf'); // 你的文件地址
    // 讀取文件
    const file = fs.readFileSync(filePath);
    // 設置響應類型為pdf
    ctx.set('Content-Type', 'application/pdf');
    // 設置響應頭,使其可以下載,你可以設置你想要的文件名
    ctx.set('Content-Disposition', 'attachment; filename=jianli.pdf');
    // 將文件內容賦值給response.body
    ctx.body = file;
});

app.listen(3000, () => {
    console.log('Server is running at http://localhost:3000');
});
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容