前端实现文件下载的方法

news2025/7/8 13:54:41

前端实现文件下载

前端下载一般分为两种情况,一种是后端直接给一个文件地址,通过浏览器打开就可以下载,另外一种则需要发送请求,后端返回二进制流数据,前端解析流数据,生成URL,实现下载。

一、location.href

对于一些浏览器无法识别的文件格式,可以直接再浏览器地址栏输入url即可触发浏览器的下载功能。对于单文件下载没有什么问题,但是如果下载多文件,点击过快就会重置掉前面的请求

适用场景:

  • get请求
  • 单文件下载
window.location.href = url;

二、window.open

和location.href类似

window.open(url);

三、a标签

直接下载仅适用于浏览器无法识别的文件。如果是浏览器支持的文件格式,如html、jpg、png、pdf等,则不会触发文件下载,而是直接被浏览器解析并展示,这种情况下,可以使用a标签下载文件,download属性可以设置文件名。适用于单文件下载,如果下载多文件,点击过快就会重置掉前面的请求。

适用场景:

  • get请求
  • 单文件下载
  • 需要自定义文件名
//写法1
const download = (filename, url) => {
    let a = document.createElement('a'); 
    a.style = 'display: none'; // 创建一个隐藏的a标签
    a.download = filename;
    a.href = url;
    document.body.appendChild(a);
    a.click(); // 触发a标签的click事件
    document.body.removeChild(a);
}
// 写法2
<a href="/images/download.jpg" download="myFileName">

注意:有时候对于浏览器可识别的文件格式,我们还是需要直接下载的情况,可以声明一下文件的header的 Content-Disposition信息,告诉浏览器,该链接为下载附件链接,并且可以声明文件名

Content-Disposition: attachment; filename="filename.xls"

四、文件流

如果需要使用post请求,且后端返回是一个文件流形式,那么前端需要自己将文件流转成链接,然后下载。 二进制流大概长这样: image.png 适用场景:

  • post请求
  • get请求
  • 多文件

1.请求的方式

注意:不可以使用JQuery,因为JQuery不支持blob类型。

原生js写法

const req = new XMLHttpRequest();
req.open('POST', '/download/excel', true);
req.responseType = 'blob'; //如果不指定,下载后文件会打不开
req.setRequestHeader('Content-Type', 'application/json');
req.onload = function() {
    var content = req.getResponseHeader("Content-Disposition") ;
    // 文件名最好用后端返的Content-disposition
    // 需要后端设置 Access-Control-Expose-Headers: Content-disposition 使得浏览器将该字段暴露给前端
    var name = content && content.split(';')[1].split('filename=')[1];
    var fileName = decodeURIComponent(name)
    downloadFile(req.response,fileName)
};
req.send( JSON.stringify(params));

axios写法

download(url: string, body: any, fileName: string, method?) {
	return axios({
	  method: method ||'post',
	  headers: {
	    'Content-Type': 'application/json; charset=utf-8'
	  },
	  url,
	  responseType: 'blob',
	  headers: { //如果需要权限下载的话,加在这里
	        Authorization: '123456'
	    }
	  data: JSON.stringify(params),
	  timeout: 60 * 1000
	}).then((res: any) => {
	   if (!res) {
	     message.error('下载失败')
	     return
	   }
	   console.log('res:', res)
	   let url = window.URL.createObjectURL(new Blob([res], { type: 'application/vnd.ms-excel' }))
	   let link = document.createElement('a')
	   link.style.display = 'none'
	   link.href = url
	   if (!fileName || typeof fileName != "string") {
	     fileName = "下载文件"
	   }
	   link.setAttribute('download', fileName + '.xlsx')
	   document.body.appendChild(link)
	   link.click()
	   document.body.removeChild(link); //下载完成移除元素
	   window.URL.revokeObjectURL(url); //释放掉blob对象
	 })
}

2.文件下载的方式

通过URL.createObjectURL()下载

URL.createObjectURL() 静态方法会创建一个DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的document绑定。

downloadFile:function(data,fileName){
    // data为blob格式
    var blob = new Blob([data]);
    var downloadElement = document.createElement('a');
    var href = window.URL.createObjectURL(blob);
    downloadElement.href = href;
    downloadElement.download = fileName;
    document.body.appendChild(downloadElement);
    downloadElement.click();
    document.body.removeChild(downloadElement);
    window.URL.revokeObjectURL(href);
}

通过# FileReader.readAsDataURL()下载

readAsDataURL() 方法会读取指定的 Blob 或 File 对象。读取操作为异步操作,当读取完成时,可以从onload回调函数中通过实例对象的result属性获取data:URL格式的字符串(base64编码),此字符串即为读取文件的内容,可以放入a标签的href属性中。

downloadFile:function(data,fileName){
   const reader = new FileReader()
   // 传入被读取的blob对象
   reader.readAsDataURL(data)
   // 读取完成的回调事件
   reader.onload = (e) => {
       let a = document.createElement('a')
       a.download = fileName
       a.style.display = 'none'
       // 生成的base64编码
       let url = reader.result
       a.href = url
       document.body.appendChild(a)
       a.click()
       document.body.removeChild(a)
   }
}

两者的区别

  • 返回值

FileReader.readAsDataURL(blob)可以得到一段base64的字符串
URL.createObjectURL(blob)得到的是当前文件的一个内存url

  • 内存

FileReader.readAsDataURL(blob)依照js垃圾回收机制自动从内存中清理 URL.createObjectURL(blob)存在于当前document内,清除方式通过revokeObjectURL()手动清除

  • 执行方式

FileReader.readAsDataURL(blob)通过回调的方式f返回,异步执行
URL.createObjectURL(blob) 直接返回,同步执行

  • 多个文件

FileReader.readAsDataURL(blob)同时处理多个文件时,需要一个文件对应一个FileReader对象
URL.createObjectURL(blob) 依次返回,没有影响

  • 优势对比

URL.createObjectURL(blob)得到本地内存容器的URL地址,方便预览,需要注意手动释放内存的问题,性能优秀。
FileReader.readAsDataURL(blob)可直接转为base64格式,直接用于业务

五、插件downloadjs

下载

 npm install --save downloadjs

引入插件

import download from "downloadjs"
// or
const download = require('downloadjs')

使用

  export const downloadFile = (res, type, filename) => {
    // 将二进制流转成blob对象
    const blob = new Blob([res], {
      type: type
    })
    // 调用插件方法
    download(blob, filename, type);
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/406023.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

css添加边框阴影

css边框阴影如何设置&#xff1f; 语法&#xff1a; <style> box-shadow: h-shadow v-shadow blur spread color inset; </style> 取值&#xff1a; h-shadow&#xff1a;必需设置的值&#xff0c;定义水平阴影的位置。允许负值。 v-shadow&#xff1a;必需设置…

微信小程序web-view与H5 通信方式探索

本文作者为奇舞团前端开发工程师小程序简介小程序是一种全新的连接用户与服务的方式&#xff0c;它可以在微信内被便捷地获取和传播&#xff0c;同时具有出色的使用体验。需求微信小程序 H5 混合开发就是 在一个小程序中&#xff0c;采用部分小程序原生页面&#xff0c;部分通过…

Vue组件通信——父子组件通信的四种方法

引入组件 全局引入 在main.js文件中引入并注册 import ChildrenDemo from /views/components/ChildrenDemo Vue.component(ChildrenDemo,ChildrenDemo)// 第一个参数 全局组件的名字(字符串类型)&#xff0c;第二个参数&#xff1a;引入的组件名&#xff08;一般都与组件名保持…

【前端开发环境安装、配置、项目搭建全教程】

前端开发环境安装、配置、项目搭建全教程 1.Node环境安装 简单的说 Node.js 就是运行在服务端的 JavaScrip&#xff0c;基于 Chrome JavaScript 运行时建立的一个平台&#xff0c;Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境&#xff0c;基于 Google 的 V8 引擎&…

uniapp页面跳转的几种方式

uniapp页面跳转的几种方式 一、uni.navigateTo 定义&#xff1a;保留当前页面&#xff0c;跳转到应用内的某个页面&#xff0c;使用uni.navigateBack可以返回到原页面。使用&#xff1a; // 1.不传参 uni.navigateTo({url:./home/index }); // 2.传参字符串 uni.navigateTo(…

Vue后台管理系统模板

推荐一些 Vue 常用后台管理系统模板 前言 Vue.js 是一个目前比较流行的前端框架&#xff0c;已经到了前端人人都会的地步&#xff0c;今天这里为大家罗列一下基于 Vue 的后端管理的框架。目前比较流行和 Vue 搭配的 UI组件 有Element-UI、iview、Bootstrap-Vue、Ant-Design-V…

项目中报错 Uncaught (in promise)

项目中报错 Uncaught (in promise) 一、问题&#xff1a;当你调用 Promise.reject() 回调的时候&#xff0c;Chrome 控制台中出现一条警告消息“Uncaught (in promise)”。 例如你简单封装axios的响应拦截器的时候&#xff1a; // 响应拦截 service.interceptors.response.u…

VUE 富文本编辑器 tinymce - - - - 对懒人 非常友好 一看就懂

首先个人觉得 tinymce这个富文本编辑器是最好用 最编辑的 &#xff0c;对懒人非常友好 的一款编辑器&#xff0c;刚 有哟个项目 &#xff0c;就遇到了 使用富文本编辑的坑 &#xff0c;因为赶项目进度自己在网上随便找了一个富文本编器&#xff0c;就是 quill 这个 坑 实在太多…

【个人网站】零基础个人网站搭建完整教程(附免费源码)

零基础个人网站搭建完整教程&#xff08;一&#xff09; 内容包括&#xff1a;前端搭建后端搭建源码网盘链接搭建服务器网站上线&#xff08;完整教程&#xff09; 从0到1搭建网站零基础个人网站搭建完整教程&#xff08;一&#xff09;前言一、前端搭建一、副页设计1.显示文字…

最新Eclipse安装教程(2022-09)

前言 现在是在校大学生&#xff0c;未来想从事大数据相关的工作&#xff0c;目前在b站学习大数据&#xff0c;写这些的目的是为了整理、巩固学过的知识&#xff0c;以后自己工作了也可以回头看看&#xff0c;如果还能够帮助到大家&#xff0c;就再好不过了&#xff01; 一、Ec…

Python Flask框架-开发简单博客-项目布局、应用设置

作者&#xff1a;Eason_LYC 悲观者预言失败&#xff0c;十言九中。 乐观者创造奇迹&#xff0c;一次即可。 一个人的价值&#xff0c;只在于他所拥有的。所以可以不学无术&#xff0c;但不能一无所有&#xff01; 技术领域&#xff1a;WEB安全、网络攻防 关注WEB安全、网络攻防…

Vue3父子组件通讯一目了然

文章目录&#x1f31f; 写在前面&#x1f31f; 父 &#x1f449; 子&#x1f31f; 子 &#x1f449; 父&#x1f31f; 写在最后&#x1f31f; 写在前面 专栏介绍&#xff1a; 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章&#xff0c;应粉丝要求开始更新 Vue3 的相关技术文…

前端直接生成GIF动态图实践

前言去年在博客中发了两篇关于GIF动态生成的博客&#xff0c;GIF图像动态生成-JAVA后台生成和基于FFmpeg的Java视频Mp4转GIF初探&#xff0c;在这两篇博客中都是采用JAVA语言在后台进行转换。使用JAVA的同学经过自己的改造和开发也可以应用在项目上。前段时间有朋友私下问&…

chatgpt这么火?前端如何实现类似chatgpt的对话页面

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;…

【毕业季|进击的技术er】作为一名职场人,精心总结的嵌入式学习路线图

活动地址&#xff1a;毕业季进击的技术er 文章目录0、作者介绍1、前言2、嵌入式基础必备知识2.1、学习内容2.2、学习建议2.3、学习资料3、嵌入式入门篇——51单片机3.1、学习内容3.2、学习建议3.3、学习资料4、STM32进阶篇4.1、学习内容4.2、学习建议4.3、学习资料5、小而美的R…

目标跟踪算法综述

前言: 目标跟踪是计算机视觉领域研究的一个热点问题&#xff0c;其利用视频或图像序列的上下文信息&#xff0c;对目标的外观和运动信息进行建模&#xff0c;从而对目标运动状态进行预测并标定目标的位置。目标跟踪算法从构建模型的角度可以分为生成式(generative)模型和判别…

Vue--》搭配Bootstrap实现Vue的列表增删功能

在日常开发中&#xff0c;我们可以用 “拿来主义” 借助Bootstarp现成的一些样式&#xff0c;快速生成我们想要的页面布局&#xff0c;避免书写大量的HTML和CSS代码&#xff0c;省下了许多不必要的时间。 当我们想要生成表单表格时我们可以查看Bootstrap的官方文档&#xff0c;…

vue2响应式原理

首先要知道vue2 是2013年 基于 ES5开发出来的 我们常说的重渲染就是重新运行render函数 vue2响应式原理简单来说就是vue官网上的这图片 通过 Object.defineProperty 遍历对象的每一个属性&#xff0c;把每一个属性变成一个 getter 和 setter 函数&#xff0c;读取属性的时候…

前端学习之CSS

目录 引言 1. 什么是CSS? 2. 在HTML中使用CSS的三方式(基于CSS2. 0) 2.1 内联定义 2.2 样式块 2.3 引入文件 引言 大家不要觉得CSS也是一种语言&#xff0c;需要花费很多的时间去学习&#xff0c;不要恐惧它&#xff0c;其实CSS只是一个很小的知识点&#xff0c;我们在…

【web渗透】SSRF漏洞超详细讲解

&#x1f495;&#x1f495;&#x1f495; 博主昵称&#xff1a;摆烂阳&#x1f495;&#x1f495;&#x1f495; &#x1f970;博主主页跳转链接 &#x1f469;‍&#x1f4bb;博主研究方向&#xff1a;web渗透测试 、python编程 &#x1f4c3; 博主寄语&#xff1a;希望本篇文…