前端實現(xiàn)文件下載的4種常見方式與實戰(zhàn)示例
引言
在前端開發(fā)中,實現(xiàn)文件下載是一個非常常見的需求,例如:
- 下載圖片、PDF、Excel 等文件
- 將前端生成的數(shù)據(jù)導(dǎo)出為文件(如 JSON、CSV、Excel)
- 使用 Blob、Data URL、Stream 方式進行下載
本篇文章將介紹 4 種前端文件下載的方式,并提供詳細示例,幫助你掌握文件下載的各種技巧。
1. 直接使用 <a> 標(biāo)簽下載(適用于靜態(tài)文件)
原理
HTML <a> 標(biāo)簽的 download 屬性可以直接下載鏈接文件,無需 JavaScript 處理。
示例:下載本地文件
<a href="/files/example.pdf" rel="external nofollow" download="example.pdf">下載 PDF 文件</a>
說明:
- href="/files/example.pdf" 指向文件路徑
- download="example.pdf" 指定下載時的文件名稱
示例:下載網(wǎng)絡(luò)圖片
<a rel="external nofollow" download="my-image.jpg">下載圖片</a>
注意:
- 僅適用于同源文件
- 跨域文件 需要服務(wù)器支持 Access-Control-Allow-Origin
2. 使用 JavaScript Blob 方式下載文件
原理
Blob(二進制大對象)可以用來存儲二進制數(shù)據(jù),并創(chuàng)建可下載的 URL。
示例:下載文本文件
function downloadTextFile() {
const content = "Hello, this is a text file!";
const blob = new Blob([content], { type: "text/plain" }); // 創(chuàng)建 Blob
const url = URL.createObjectURL(blob); // 生成臨時 URL
const a = document.createElement("a");
a.href = url;
a.download = "example.txt"; // 設(shè)置下載文件名
document.body.appendChild(a);
a.click(); // 觸發(fā)下載
document.body.removeChild(a);
URL.revokeObjectURL(url); // 釋放 URL
}
downloadTextFile();
適用場景:前端生成文件,如文本、JSON、CSV、HTML。
3. 使用 fetch 下載文件(適用于后端 API 提供的文件)
原理
使用 fetch() 請求文件,并將其轉(zhuǎn)換為 Blob 進行下載。
示例:下載后端提供的文件
async function downloadFileFromServer(url, filename) {
const response = await fetch(url);
const blob = await response.blob(); // 將響應(yīng)轉(zhuǎn)換為 Blob
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(a.href);
}
// 調(diào)用示例
downloadFileFromServer("https://example.com/report.pdf", "report.pdf");
適用場景:
- 后端提供的文件下載
- Excel、PDF、圖片等二進制文件
4. 使用 canvas 生成圖片并下載
原理
canvas.toBlob() 可以將 canvas 畫布轉(zhuǎn)換為 Blob,然后使用 URL.createObjectURL() 進行下載。
示例:下載 canvas 生成的圖片
<canvas id="myCanvas" width="200" height="200"></canvas>
<button onclick="downloadCanvas()">下載圖片</button>
<script>
function downloadCanvas() {
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
// 畫一個紅色矩形
ctx.fillStyle = "red";
ctx.fillRect(50, 50, 100, 100);
// 將 canvas 轉(zhuǎn)換為 Blob 并下載
canvas.toBlob(blob => {
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "canvas-image.png";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}, "image/png");
}
</script>
適用場景:截圖、繪圖工具、導(dǎo)出 canvas 生成的圖像。
5. 額外優(yōu)化:進度顯示 & 大文件下載
對于 大文件下載,可以使用 ReadableStream 進行流式下載,并顯示進度。
示例:下載大文件并顯示進度
async function downloadLargeFile(url, filename) {
const response = await fetch(url);
const reader = response.body.getReader();
const contentLength = +response.headers.get("Content-Length");
let receivedLength = 0;
let chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
receivedLength += value.length;
console.log(`下載進度:${((receivedLength / contentLength) * 100).toFixed(2)}%`);
}
const blob = new Blob(chunks);
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(a.href);
}
// 調(diào)用示例
downloadLargeFile("https://example.com/large-file.zip", "large-file.zip");
適用場景:大文件下載、斷點續(xù)傳、流式處理。
6. 前端下載文件的最佳實踐
| 方法 | 適用場景 | 優(yōu)點 | 缺點 |
|---|---|---|---|
| <a> 標(biāo)簽 | 靜態(tài)文件 | 簡單易用 | 僅適用于同源文件 |
| Blob + URL.createObjectURL() | 前端生成文件 | 適用于所有文件類型 | 需手動釋放 URL |
| fetch() 方式 | API 提供的文件下載 | 適用于二進制數(shù)據(jù) | 需處理 CORS 問題 |
| canvas.toBlob() | 生成圖片并下載 | 適用于 canvas | 僅適用于 canvas 內(nèi)容 |
| 流式下載 (ReadableStream) | 大文件、進度控制 | 適合斷點續(xù)傳 | 代碼復(fù)雜 |
結(jié)論
前端實現(xiàn)文件下載的方式多種多樣,選擇合適的方式取決于 文件來源 和 下載需求:
靜態(tài)文件:使用 <a> 標(biāo)簽的 download 屬性(簡單易用)
動態(tài)生成文件:使用 Blob + URL.createObjectURL()
從服務(wù)器下載文件:使用 fetch() 請求文件并轉(zhuǎn)換為 Blob
大文件或流式下載:使用 ReadableStream 進行分塊處理
到此這篇關(guān)于前端實現(xiàn)文件下載的4種常見方式與實戰(zhàn)示例的文章就介紹到這了,更多相關(guān)前端文件下載方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序?qū)崿F(xiàn)image組件圖片自適應(yīng)寬度比例顯示的方法
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)image組件圖片自適應(yīng)寬度比例顯示的方法,簡單講述了image組件的常用屬性,并結(jié)合實例形式分析了微信小程序?qū)崿F(xiàn)圖片自適應(yīng)寬度比例的相關(guān)操作技巧,需要的朋友可以參考下2018-01-01
微信小程序調(diào)用騰訊地圖API文檔JavaScript?SDK和WebService?API詳細解讀
本文介紹了如何使用騰訊位置服務(wù),包括申請開發(fā)者密鑰、獲取小程序APPID、下載地圖SDK、設(shè)置服務(wù)器域名白名單等步驟,詳細說明了如何在微信小程序中集成騰訊位置服務(wù),進行地圖展示和周邊搜索等功能的實現(xiàn),同時提醒注意API的調(diào)用次數(shù)和權(quán)限限制,需要的朋友可以參考下2024-09-09
Javascript將數(shù)字轉(zhuǎn)化成為貨幣格式字符串
這篇文章主要介紹Javascript將數(shù)字轉(zhuǎn)化成為貨幣格式字符串的方法,通俗易懂,需要的朋友可以參考下。2016-06-06
js中使用replace方法完成某個字符的轉(zhuǎn)換
這篇文章主要介紹了js中使用replace方法完成某個字符的轉(zhuǎn)換,比較實用,需要的朋友可以參考下2014-08-08
詳解javaScript中Number數(shù)字類型的使用
Number和Math都屬于JavaScript中的內(nèi)置對象,Number數(shù)字類型作為基礎(chǔ)數(shù)據(jù)類型,我們在開發(fā)過程中會經(jīng)常用到,包括數(shù)字精度的格式化,還有字符串轉(zhuǎn)換成數(shù)字等操作。本文將詳細講解其用法,感興趣的可以了解一下2022-04-04
基于javascript實現(xiàn)listbox左右移動
這篇文章主要介紹了基于javascript實現(xiàn)listbox左右移動的相關(guān)資料,以一個完整的實例代碼分析了js實現(xiàn)listbox左右移動的相關(guān)技巧,感興趣的小伙伴們可以參考一下2016-01-01

