引言
在前端开发中,实现文件下载是一个非常常见的需求,例如:
- 下载图片、PDF、Excel 等文件
- 将前端生成的数据导出为文件(如 JSON、CSV、Excel)
- 使用 Blob、Data URL、Stream 方式进行下载
本篇文章将介绍 4 种前端文件下载的方式,并提供详细示例,帮助你掌握文件下载的各种技巧。
1. 直接使用 <a> 标签下载(适用于静态文件)
原理
HTML <a> 标签的 download 属性可以直接下载链接文件,无需 JavaScript 处理。
示例:下载本地文件- <a href="/files/example.pdf" rel="external nofollow" download="example.pdf">下载 PDF 文件</a>
复制代码 说明:
- href="/files/example.pdf" 指向文件路径
- download="example.pdf" 指定下载时的文件名称
示例:下载网络图片- <a href="https://example.com/image.jpg" rel="external nofollow" download="my-image.jpg">下载图片</a>
复制代码 注意:
- 仅适用于同源文件
- 跨域文件 需要服务器支持 Access-Control-Allow-Origin
2. 使用 JavaScript Blob 方式下载文件
原理
Blob(二进制大对象)可以用来存储二进制数据,并创建可下载的 URL。
示例:下载文本文件- function downloadTextFile() {
- const content = "Hello, this is a text file!";
- const blob = new Blob([content], { type: "text/plain" }); // 创建 Blob
- const url = URL.createObjectURL(blob); // 生成临时 URL
- const a = document.createElement("a");
- a.href = url;
- a.download = "example.txt"; // 设置下载文件名
- document.body.appendChild(a);
- a.click(); // 触发下载
- document.body.removeChild(a);
- URL.revokeObjectURL(url); // 释放 URL
- }
- downloadTextFile();
复制代码 适用场景:前端生成文件,如文本、JSON、CSV、HTML。
3. 使用 fetch 下载文件(适用于后端 API 提供的文件)
原理
使用 fetch() 请求文件,并将其转换为 Blob 进行下载。
示例:下载后端提供的文件- async function downloadFileFromServer(url, filename) {
- const response = await fetch(url);
- const blob = await response.blob(); // 将响应转换为 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);
- }
- // 调用示例
- downloadFileFromServer("https://example.com/report.pdf", "report.pdf");
复制代码 适用场景:
- 后端提供的文件下载
- Excel、PDF、图片等二进制文件
4. 使用 canvas 生成图片并下载
原理
canvas.toBlob() 可以将 canvas 画布转换为 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 转换为 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>
复制代码 适用场景:截图、绘图工具、导出 canvas 生成的图像。
5. 额外优化:进度显示 & 大文件下载
对于 大文件下载,可以使用 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);
- }
- // 调用示例
- downloadLargeFile("https://example.com/large-file.zip", "large-file.zip");
复制代码 适用场景:大文件下载、断点续传、流式处理。
6. 前端下载文件的最佳实践
方法适用场景优点缺点<a> 标签静态文件简单易用仅适用于同源文件Blob + URL.createObjectURL()前端生成文件适用于所有文件类型需手动释放 URLfetch() 方式API 提供的文件下载适用于二进制数据需处理 CORS 问题canvas.toBlob()生成图片并下载适用于 canvas仅适用于 canvas 内容流式下载 (ReadableStream)大文件、进度控制适合断点续传代码复杂
结论
前端实现文件下载的方式多种多样,选择合适的方式取决于 文件来源 和 下载需求:
静态文件:使用 <a> 标签的 download 属性(简单易用)
动态生成文件:使用 Blob + URL.createObjectURL()
从服务器下载文件:使用 fetch() 请求文件并转换为 Blob
大文件或流式下载:使用 ReadableStream 进行分块处理
到此这篇关于前端实现文件下载的4种常见方式与实战示例的文章就介绍到这了,更多相关前端文件下载方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:https://www.jb51.net/javascript/3396771f9.htm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
|