vue实现文件下载

news2025/1/26 15:33:43

引言

最近在自己做项目的需求的过程中,需要vue+springboot实现文件的下载功能(导出博客文件)。

问题重现

在我后端文件下载接口开发完成后,使用vue前端去进行对接时出现了问题。

我是直接使用的axios去进行请求接口,请求接口后返回的状态码是200,但是就是不会自动下载文件。

起初我一直以为是我后端接口有问题,后才发现我们如果在vue中通过button发送axios请求文件下载的接口,那么是不会去进行自动下载文件的,必须要在a标签中去进行调用,才会自动下载文件,所以我们在axios请求完成后,在js中去调用a标签即可

问题解决

经过寻找资料,发现vue通过axios请求后是不会自动下载文件的,需要我们自己去做一些配置(只能通过a标签去进行文件的下载)

  1. axio中需要添加responseType,以此来辨别它的请求类型

    responseTypeblob即可

    export function exportArticleList(data){
      return request({
        url: '/article/exportArticleList',
        method: 'post',
        data: data,
        responseType: 'blob'
      })
    }
    
  2. 后端返回response后,我们需要做些处理,我们需要使用a标签将其打开下载,如下示例:

    由于我前端使用的vue-admin-template模板,所以直接在request.js中进行response统一处理即可。

    如果返回的response中的headerscontent-type的值为application/octet-stream;charset=UTF-8,则我们判定它有需要下载的文件,然后我们调用a标签来进行下载

    **注意:**vue的response可能获取不到content-disposition的值,我们需要在后端进行对于处理才行

    后端处理:

    //在vue的response中显示Content-Disposition
    response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
    // 设置在下载框默认显示的文件名
    response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFileName, "UTF-8")+".zip");
    
    const res = response.data
    
    console.log(response)
    //获取请求的类型
    const respContentType = response.headers['content-type']
    if (respContentType === 'application/octet-stream;charset=UTF-8') {
      console.log("有文件类型的流")
      if (!res) {
        return
      }
      //由于后台返回文件名称是通过response返回的
      //因此需要从response headers中content-disposition响应头中获取文件名称fileName
      let fileName = response.headers["content-disposition"];
      fileName = fileName.split('=')[1]
      const url = window.URL.createObjectURL(new Blob([res], {
        type: 'application/octet-stream;charset=UTF-8'
      }))
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
     //decodeURIComponent解决文件名的url转码问题
      link.setAttribute('download', decodeURIComponent(fileName))
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      return
    }
    

解决完成

点击导出可以成功下载文件

image-20221212114049652

其它问题

URL转码问题

由于后端传来前端的文件名是经过url转码的,所以中文会出现乱码的情况

vue中使用如下命令即可进行解码

// 解码用
decodeURIComponent(str)
// 编码用
encodeURIComponent(str)

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

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

相关文章

Python 炫技操作:条件语句的七种写法

原代码 这是一段非常简单的通过年龄判断一个人是否成年的代码,由于代码行数过多,有些人就不太愿意这样写,因为这体现不出自己多年的 Python 功力。 if age > 18:return "已成年" else:return "未成年"下面我列举了六…

SwiftUI 中创建谷歌字体浏览器

Google Fonts是设计用户界面时使用的免费字体的转到站点。本教程将展示如何编写一个简单的工具来预览这些字体,而无需在系统中注册每种字体。 该应用程序包含一个拆分视图,该视图在左侧面板中包含字体列表。右侧面板将显示字体样式选项的预览。 项目设置 创建一个名为 Googl…

Vue2之webpack篇(一)

目录 前言 1、什么是webpack? 2、传统开发模式 一、传统开发模式 1、场景 2、问题 3、原因 4、解决方案 二、ES6模块化 1、ES6的解决方案 3、拓展 4、取别名 5、*搭配取别名 6、导出default{} 三、CommonJS规范 1、推荐文档 2、使用CommonJS规范解决方…

十二、DockerFile构建过程解析

1、概述 Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。 在Docker 常用命令篇中,我们已经知道了2中构建镜像的方式 export\import 和 commit方式。这两种方式都需要先运行并创建容器,然后在容器…

python自学之《21天学通Python》(5)

第8章 复杂程序组织 当一个应用程序简单时,将程序代码写入一个文件即可。但随着应用程序或项目复杂度增加时,如果将所有代码都写入同一个文件中时,会出现文件过长或过大,即不方便代码浏览,也不方便代码的管理、使用与维…

人工智能人才缺口暴增,想转行的你赶紧把Python学起来...

当前AI人才极度紧缺,据《中国ICT人才生态白皮书》研究分析,到2018年底,我国人工智能人才缺口将突破100万,到2020年,这一数字将攀升到226万。 在过去的几年中,Python已经成为现代软件开发,基础设…

Web测试的各个测试点,居然这么全!(文末送web测试方法大全一份)

1 什么是Web测试? Web测试测试Web或Web应用程序的潜在错误。它是在上线前对基于网络的应用程序进行完整的测试。 UI测试功能测试数据库测试性能测试兼容性测试安全测试自动化测试 2 WEB测试主要测试场景 1.UI测试 界面是否美观,风格、字体、样式是否…

初识: 对象的属性特征

1. 前言 2. 什么是对象的属性特征 3. 灵活控制对象的属性特征 4. configurable: false 是单向设置的 1. 前言 众所周知,默认情况下我们可以任意对自己定义的对象进行增删改的。但是,在某些情况下,我们不能让别人去随便修改我们定义的对象的…

《数据结构》二叉数

学习目录树型结构概念树的重要概念树的表示形式二叉数概念特殊的二叉树二叉树的性质练习题树型结构 概念 树是一种非线性的数据结构,由 n 个有限节点组成一个有层次关系的集合 它具有以下的特点: 有一个特殊的结点,称为根结点,…

【 Threejs 】- Shader 着色器实例渲染教程

着色器在threejs中是一个难点,话不多说,先来看看着色器是什么? 如果您已经有使用计算机绘图的经验,您就会知道在这个过程中您先画一个圆,然后画一个矩形、一条线、一些三角形,直到您组成您想要的图像。这个…

面试真题 | 什么是 Redis ? Redis缓存应用场景有哪些?

面试官问题 redis击穿、穿透有什么区别?如何设计用例及测试 Redis 的基本概念 在没有添加 Redis 的时候,后端的查询流程是: 用户访问页面。请求后端服务。经过逻辑处理后,去数据库查询信息。 在添加 Redis 的之后,…

MySQL 服务端口大全

介绍 MySQL默认服务端口3306/TCP都不会陌生,但MySQL提供服务只有单纯的这个端口吗。在8.0版本默认启动的时候会发现,出现新的端口。 可以说MySQL使用的端口数量取决于所启用的特性、所使用的组件、应用程序连接的方式以及环境的其他方面。 按照官方说…

转速传感器信号隔离变送器正弦波输入方波信号输出

特点 转速传感器信号直接输入,方波信号输出正弦波、锯齿波信号输入,方波信号输出200mV峰值微弱信号的放大与整形不改变原波形频率,响应速度快电源、信号:输入/输出 3000VDC三隔离辅助电源:5V、12V、15V或24V直流单电源…

Huffman编码

目录背景Huffman编码代码部分背景 在数据传输,保存的时候,特别是在数据量特别大的时候传输,保存数据是一件特别麻烦的事。比如逛淘宝的时候,首页会有很多商家展示自己产品的高清图片,如果不对图片进行压缩服务端保存图…

经历百度、美团两次被裁后,我能在小公司躺平吗?

百度裁员后我进入体制内,专心学习自动化 百度被裁后,我意识到自学效果不佳,跟不上职场的所需,于是有了系统学习的想法。 这时的新工作是在体制内,工作强度不大,时间上也比较自由,便正式成为了…

非零基础自学Golang 第12章 接口与类型 12.5 类型断言

非零基础自学Golang 文章目录非零基础自学Golang第12章 接口与类型12.5 类型断言12.5.1 ok-pattern12.5.2 switch-type第12章 接口与类型 12.5 类型断言 类型断言是使用在接口变量上的操作。 简单来说,接口类型向普通类型的转换就是类型断言。 类型断言的语法是…

【关于时间序列的ML】项目 1 :使用 Python 进行 Covid-19 病例 预测

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

rk3568 | 瑞芯微平台GPIO引脚驱动编写

最近在玩瑞芯微平台的产品,移植了几个设备的驱动,遇到了一些问题,总结后发现大部分问题都出在了GPIO配置的问题上,写下本篇文章,用来分享一下调试的心得。 有喜欢瑞芯微的朋友,可以加我好友,拉…

JVM的作用,结构

源文件经过编译,生成字节码文件 JVM执行字节码文件(实际上就是将字节码解释成具体平台上的机器指令) jdk,jre,jvm三者的关系: jvm的组成: (1)类加载器子系统:负责将.class文件加载到JVM中 (2)…

初学编程,我们应该怎么做,十年老鸟带你入门。

问问自己学编程的真正目的,仅仅是想应付考试考证,还是真心想从事编程方面的工作。仅仅处于功利性而不是真心喜欢,人生苦短,劝不要来浪费时间,找其它真心喜欢的事情。不是社会喜欢的,不是父母喜欢的&#xf…