前端实现文件下载常用几种方式
项目中前端下载一般分为两种情况:
- 后端直接提供一个文件地址,通过浏览器打开就可以下载。
- 需要发送请求,后端返回二进制流数据,前端解析流数据,生成URL实现下载。
前端对应的实质是a标签和Blob
文件下载,这两者的区别:
- a标签:txt、png、jpg、gif等文件,是不提供直接下载,有兼容性问题,特别是IE。
- blob:利用
Blob
对象可以将文件流转化成Blob
二进制对象。该对象兼容性良好,适用于需要动态生成或处理非同源文件的情况。通过URL.createObjectURL()
方法将Blob对象转换为一个临时的URL下载。
blob对象
Blob对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream
来用于数据操作。Blob对象是html5新增的对象,它的作用是用来存储二进制数据的,比如图片、视频、音频等,
属性
- size:只读属性,Blob中的字节数。
- type:只读属性,表示Blob存放的媒体类型,图片、视频、文本文件等等。
它的使用方法如下:
const blob = new Blob([], { type: '' });
URL.createObjectURL
URL.createObjectURL()
静态方法会创建一个DOMString
,其中包含一个表示参数中给出的对象的URL
。这个URL
的生命周期和创建它的窗口中的document
绑定。这个新的URL
对象表示指定的File
对象或Blob
对象。
当我们的document
被销毁后,这个URL
就会失效,所以我们需要在合适的时机销毁它。
简单说这个方法用来创建一个url
的,它的作用是把一个blob
对象转换成一个url
,这个url
可以用来下载文件,也可以用来预览文件。
// 创建下载的链接
const url = URL.createObjectURL(blob);
// 释放掉blob对象
URL.revokeObjectURL(url);
传统a标签下载
const a = document.createElement('a'); // 创建a标签
a.style = 'display: none';
a.download = filename''; // 设置下载文件名
a.href = url; // 设置下载地址
document.body.appendChild(a);
a.click(); // 触发a标签的click事件
document.body.removeChild(a);
这种方式无法解决浏览器可识别文件直接打开的问题,但是 HTML5 新属性 download 属性会解决这个问题。
a标签 + download属性
当URL
是同源(同域名、同协议、同端口号)时,这种情况用 a标签加download属性的方式即可,download属性指示浏览器该下载而不是打开该文件,同时该属性值即下载时的文件名;
<a href="path/to/file.jpg" download='file.jpg'>点击下载图片</a>
const a = document.createElement('a'); // 创建a标签
const e = document.createEvent('MouseEvents'); // 创建鼠标事件对象
e.initEvent('click', false, false); // 初始化事件对象
a.href = url; // 设置下载地址
a.download = filename || ''; // 设置下载文件名
a.dispatchEvent(e);
因为a标签下载只能下载同源的文件,如果是跨域的文件,这里包括图片、音视频等媒体文件,都是预览,也无法下载。
fetch发送请求
- 通过原生fetch请求,动态生成一个a标签实现文件下载。
res.blob()
该方法是Fetch API的response对象方法,该方法将后端返回的文件流转换为返回blob的Promise;blob(Binary Large Object)是一个二进制类型的对象,记录了原始数据信息。URL.createObjectURL(blob)
该方法的返回值可以理解为一个指向传入参数对象的url可以通过该url访问参数传入的对象。
// 将url转成blob地址
fetch(url).then(res => res.blob()).then(blob => {const a = document.createElement('a');// 将链接地址字符内容转变成blob地址a.href = URL.createObjectURL(blob);a.download = filename; // 下载文件的名字document.body.appendChild(a);a.click();// 下载完成后 清除占用的缓存资源window.URL.revokeObjectURL(a.href);document.body.removeChild(a);});
- 该方法需要注意的是,即便传入同一个对象作为参数,每次返回的url对象都是不同的。
- 该url对象保存在内存中,只有在当前文档(document)被卸载时才会被清除,因此为了更好的性能,需要通过URL.revokeObjectURL(blobUrl)主动释放。
XMLHttpRequest
XMLHttpRequest(简称XHR)是一个用于创建服务器之间通信的Web API。在下载文件时,可以通过设置responseType
为blob
来接收二进制数据。这种方法适用于需要从服务器获取文件流并进行下载的场景。与Blob类似,XHR也可以用于动态生成文件并触发下载,但它在处理异步请求和数据传输方面提供了更多的灵活性。
- 可通过xhr.setRequestHeader设置请求头参数。
- 可通过xhr.getResponseHeader(‘content-disposition’)获取头部参数。
let xhr = new XMLHttpRequest();
// GET请求,downloadURL请求路径url,async(是否异步)
xhr.open('GET', downloadURL, true);
// 设置请求头参数的方式,如果没有可忽略此行代码
xhr.setRequestHeader("Token", 'Bearer ' + getStorage().token); // token
// 设置响应类型为 blob
xhr.responseType = 'blob';
// 关键部分
xhr.onload = function () {//如果请求执行成功if (this.status === 200) {// 下载文件const blob = new Blob(this.response);const href = window.URL.createObjectURL(blob); // 创建下载的链接const a = document.createElement('a');a.href = href;a.download = fileName; // 下载文件名document.body.appendChild(a);a.click(); // 点击下载document.body.removeChild(a); // 下载完成移除元素window.URL.revokeObjectURL(href); // 释放掉blob对象// 可通过xhr.getResponseHeader('content-disposition')头部参数,文件名等// let headerParams = xhr.getResponseHeader('content-disposition')?.split(";") || [];}
};
// 发送请求
xhr.send();
xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { // 成功后操作 }
};
axios请求方式
axios({method: method ||'post',url,responseType: 'blob',headers: {'Content-Type': 'application/json; charset=utf-8'// 可在此处添加请求参数token: 'token值'}data: JSON.stringify(params)
}).then(res => {if (res) {const blob = new Blob(res);const url = window.URL.createObjectURL(blob)const a = document.createElement('a')a.style.display = 'none'a.href = href;a.download = fileName; // 下载文件名document.body.appendChild(link)link.click()document.body.removeChild(link); // 下载完成移除元素window.URL.revokeObjectURL(url); // 释放掉blob对象} else {message.error('下载失败')return;}
})
无论是通过fetch
、XMLHttpRequest
、axios
请求,处理逻辑都是请求成功后,拿到相应的response
,这个response
就是我们要下载的内容,通过将它转成blob
对象,通过URL.createObjectURL
创建下载URL
,通过a标签实现下载。
相关文章:
前端实现文件下载常用几种方式
项目中前端下载一般分为两种情况: 后端直接提供一个文件地址,通过浏览器打开就可以下载。需要发送请求,后端返回二进制流数据,前端解析流数据,生成URL实现下载。 前端对应的实质是a标签和Blob文件下载,这…...

Isaac Lab 安装 (ubuntu22.04环境)
Windows下的安装见这篇博客: Isaac Lab 安装与初体验 (windows环境)-CSDN博客 ubuntu22.04下的安装与windows下十分类似,还是参考官方的,Installation using Isaac Sim Binaries Installation using Isaac Sim Bina…...

todoList清单(HTML+CSS+JavaScript)
🌏个人博客主页: 前言: 前段时间学习了JavaScript,然后写了一个todoList小项目,现在和大家分享一下我的清单以及如何实现的,希望对大家有所帮助 🔥🔥🔥文章专题ÿ…...

LVS集群实现四层负载均衡详解(以nat,dr模式为例)
目录 一、LVS集群的介绍 1、LVS 相关术语: 2、lvs四层负载均衡工作原理 3、相关名词概念 4、lvs集群的类型 二、lvs的nat模式 1、介绍: 2、数据逻辑: 3、nat实验部署 环境搭建: 1、lvs中要去打开内核路由功能,…...
七夕表白网页效果实现与解析
七夕是中国传统的情人节,是一个充满浪漫与爱的节日。在这个特别的日子里,用代码来表达心意也是一种独特且有趣的方式。本篇文章将带你一步步实现一个简单但充满心意的七夕表白网页。通过使用HTML、CSS和少量的JavaScript,我们将创建一个包含跳…...
人工智能算法工程师(高级)课程11-自然语言处理之NLP的语言模型-seq2seq模型,seq+注意力与代码详解
大家好,我是微学AI,今天给大家介绍一下人工智能算法工程师(高级)课程11-自然语言处理之NLP的语言模型-seq2seq模型,seq+注意力,word2vec与代码详解。本课程面向高级人工智能算法工程师,深入讲解自然语言处理(NLP)中的关键语言模型技术,包括seq2seq模型及其增强版加入注意力…...

从PyTorch官方的一篇教程说开去(6.2 - 张量 tensor 矩阵运算等)
您的进步和反馈是我写作最大的动力,小伙伴来个三连呗!共勉~ 话不多说,书接上文,需要温习的小伙伴请移步 - 从PyTorch官方的一篇教程说开去(6.1 - 张量 tensor 基本操作)-CSDN博客 借图镇楼 - 1 - 矩阵乘…...

【网络层】直连路由、静态路由、动态路由
文章目录 路由表直连路由直连路由 技术背景直连路由 实战训练 静态路由静态路由 技术背景静态路由 概述静态路由 配置命令静态路由 实战训练 动态路由动态路由 技术背景路由协议概述路由协议分类 路由表 路由表的形成,路由的来源: 路由来源备注直连路由…...

tkinter用法总结
Tkinter 是 Python 标准库中的一个模块,用于创建图形用户界面 (GUI)。它是 Python 中最常用的 GUI 库之一,因为它集成在 Python 的标准发行版中,无需额外安装即可使用。 一、基本用法 1. 简单示例 import tkinter as tk# 创建主窗口 root …...

iOS基础-Block
系列文章目录 文章目录 系列文章目录一、Block是什么二、Block的使用场景1. 异步操作和完成处理器2. 动画3. 集合操作4. 定时器5. 自定义控件的事件处理6.错误处理 三、Block的底层实现1.结构分析2.Block的类型3.Block的copy4.变量捕捉 四、Block的使用细节1.auto变量的生命周期…...

本地图片瀑布流浏览器asonry Image Viewer
本地图片瀑布流浏览器asonry Image Viewer 前言效果图部分源码领取完整源码下期更新 前言 一款采用 HTML 的瀑布流本地图片浏览器「Masonry Image Viewer」只需要把你的图片文件夹拖到下载的 index 网页文件里面就可以实现瀑布流效果。项目免费开源,据介绍采用了HT…...

macos重装系统 启动U盘制作方法 - createinstallmedia 命令使用方法总结
macos重装系统比windows要稍微复杂一些,不过还好,macos系统安装app这个Apple官方提供的系统软件里面默认就内置了一个可用为我们制作启动盘的工具 createinstallmedia 我们下载的apple安装镜像要门是 dmg/pkg/iso 的压缩档案格式的,要么是 x…...

八问八答搞懂Transformer内部运作原理
最近这一两周看到不少互联网公司都已经开始秋招提前批了。 不同以往的是,当前职场环境已不再是那个双向奔赴时代了。求职者在变多,HC 在变少,岗位要求还更高了。 最近,我们又陆续整理了很多大厂的面试题,帮助一些球友…...

MySQL增删改查(基础)
1、. 新增(Create) 语法: INSERT [INTO] table_name[(column [, column] ...)] VALUES (value_list) [, (value_list)] ... 例子: -- 创建一张学生表 DROP TABLE IF EXISTS student; CREATE TABLE student (id INT,sn INT com…...

Cairo库移植到安卓记录
前言 接Android Studio引入ndk编译的so库的故事,这个东西搞了两周以后,由于自己不熟悉Java和安卓开发,踩了不少坑,其中一周时间都是花在怎么用Android Studio上的。。。AS下的新版本Koala,结果网上资料全是旧版本&…...
Redis 哈希类型的常用命令总结
1. hset 设置哈希表中字段的值。 hset key field value示例: hset user:1000 name "Alice"2. hget 获取哈希表中字段的值。 hget key field示例: hget user:1000 name3. hgetall 获取哈希表中所有的字段和值。 hgetall key示例&#x…...
【物联网设备端开发】ESP开发工具:QEMU如何模拟以太网口接入网络
以太网口支持 ESP-IDF中添加了对Opencores以太网MAC的支持。 运行以太网示例时,启用CONFIG_EXAMPLE_CONNECT_ETHERNET和 CONFIG_EXAMPLE_USE_OPENETH.。运行自定义应用程序时,启用CONFIG_ETH_USE_OPENETH 并初始化以太网驱动程序,如示例 /c…...
Python学习笔记(四)
# 数据容器分为5类,分别是:列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)""" 演示数据容器之:list列表 语法:[元素ÿ…...
跨域:安全分步实施指南
什么是跨域问题? 跨域(Cross-Origin Resource Sharing,CORS)问题发生在浏览器的同源策略(Same-Origin Policy)限制下。当一个域上的网页试图访问另一个域上的资源时,浏览器会阻止这些操作以保护…...

【iOS】AutoreleasePool自动释放池的实现原理
目录 ARC与MRC项目中的main函数自动释放池autoreleasepool {}实现原理AutoreleasePoolPage总结 objc_autoreleasePoolPush的源码分析autoreleaseNewPageautoreleaseFullPageautoreleaseNoPage autoreleaseFast总结 autorelease方法源码分析objc_autoreleasePoolPop的源码分析po…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...

ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...