前端同学们,你们知道如何应对后端通过响应体返回文件流吗?

简介: 今天给大家带来一个小知识,那就是分别从前端和后端同学的不同角度看他们是如何处理文件下载的,这个知识不光能有助于我们处理文件导出的需求,也能加深我们对HTTP协议的理解。

前言

今天说一个简单实用的小知识,在做一些管理系统时,我们往往会遇到导出Excel报表的需求,往往呢比较传统的方式就是后端借助POI工具包,或者是easyPOI,EasyExcel等更为简单,封装性更强的工具去做,使用这些工具往往就是将需要导出的文件以二进制流的方式通过HTTP请求的响应体传输。当然现在前端的功能也越来越强大,更为优雅的方式就是后端提供查询数据的接口,让前端同学去生成Excel文件,这样更能节约服务器资源,充分利用客户端的能力。

本篇文章主要是介绍传统的后端生成文件的形式,以及前端如何将后端返回的文件流进行下载。

后端出招

后端我们需要做的就是查询需要的数据,并且封装一个导出Excel文件的通用工具类,将一些导出信息传入工具类即可完成下载,本文我们以EasyExcel为例,这个工具很好用,导出的表头我们只需要通过注解配置即可。

下面便是我们需要封装的工具方法,我们只需要传入response、导出文件的文件名,数据,数据的DTO类,sheet的名称即可

这里我们需要关注几个点

  • response.setContentType("application/vnd.ms-excel");

    这个是指定网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件,这就是经常看到一些链接点击后是图片或者下载文件(每一种对应不同的文件扩展名))。

    • Content-Type: text/html; charset=utf-8: 网页格式(通过HTTP获取网页就是这种类型) .htm
    • Content-Type: application/json: JSON数据格式(我们经常写的前后端分离项目RestController的接口返回类型就是这个)
    • Content-Type: application/vnd.ms-excel: excel格式 .xls
    • Content-Type: application/pdf:pdf格式 .pdf
    • Content-Type: image/jpeg :jpg图片格式 .jpeg
    • ...
  • response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEnCode + ".xlsx");

    Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。

    这里需要注意的是中文的文件名往往需要指定字符编码,防止乱码。

  • response.getOutputStream()

    以字节流输出,我们只需要将数据写入response.getOutputStream()的输出流中

    举例:response.getOutputStream().write("计算机".getBytes());

    /**
     * 导出 Excel
     * @param response  HttpServletResponse
     * @param fileName  文件名
     * @param list      数据
     * @param clazz   导出结构体
     * @param sheetName 导入文件的 sheet 名
     */
    public static <T> void writeExcel(HttpServletResponse response, String fileName, List<T> list, Class<T> clazz, String sheetName) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileNameEnCode = URLEncoder.encode(fileName, "UTF-8").replaceAll("\+", "+");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEnCode + ".xlsx");
        writeExcel(response.getOutputStream(), list, clazz, sheetName);
    }

后端我们只需要做这些操作即可,这样我们就可以通过HTTP向前端返回一个标准的携带文件的响应.

前端接招

我们前端同学在接收到这样请求,该如何去处理呢?

如果没有做过文件下载的前端同事可能一脸懵,怀疑后端给返回的这是什么鬼,满屏乱码,离谱

如果一个深入研究过HTTP的前端同学可能会对上述请求头的参数有所了解

通过HTTP的Content-Type和Content-disposition看出端倪,知道后端返回的这是一个Excel文件

那前端该如何处理呢?

上代码

export const download = (data) => {
  return request({
    url:'请求地址',
    method: 'post',
    responseType:'blob',
    data: data
  })
}
​
// 下载处理逻辑
const filename = res.headers["content-disposition"];
const blob = new Blob([res.data]);
var downloadElement = document.createElement("a");
// URL.createObjectURL()方法会根据传入的参数创建一个指向该参数对象的URL. 这个URL的生命仅存在于它被创建的这个文档里. 新的对象URL指向执行的File对象或者是Blob对象.
var href = window.URL.createObjectURL(blob);
downloadElement.href = href;
downloadElement.download = decodeURIComponent(filename.split("filename=")[1]);
document.body.appendChild(downloadElement);
downloadElement.click();
document.body.removeChild(downloadElement);
// URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL. 当你要已经用过了这个对象URL,然后要让浏览器知道这个URL已经不再需要指向对应的文件的时候,就需要调用这个方法.
window.URL.revokeObjectURL(href);  

前端需要做如下几步:

  • 指定响应体类型 responseType:'blob'
  • 获取后端定义的文件名const filename = res.headers["content-disposition"];
  • 构建一个a标签
  • 创建指向blob的链接
  • 将文件名,链接设置到a标签上
  • 将a标签添加到document上
  • 调用a标签点击事件
  • document删除a节点
  • 释放href指向blob
目录
相关文章
|
28天前
|
前端开发 NoSQL Java
【Java若依框架】RuoYi-Vue的前端和后端配置步骤和启动步骤
本文介绍了如何配置和启动基于Java的若依(RuoYi)项目,涵盖后端和前端的详细步骤。首先,准备Redis、MySQL以及IDE(如Idea和VS)。接着,通过GitHub获取代码并导入到IDE中,执行必要的SQL文件和配置数据库密码。然后,启动Redis并进行相关配置。最后,按照前端配置步骤克隆前端代码库,打开终端执行命令完成前端配置。整个过程详细记录了每一步的操作,帮助开发者顺利部署若依项目。 如果你觉得有帮助,请点赞、关注和收藏,这将是我持续分享的动力!
285 1
|
2月前
|
开发框架 小程序 前端开发
圈子社交app前端+后端源码,uniapp社交兴趣圈子开发,框架php圈子小程序安装搭建
本文介绍了圈子社交APP的源码获取、分析与定制,PHP实现的圈子框架设计及代码编写,以及圈子小程序的安装搭建。涵盖环境配置、数据库设计、前后端开发与接口对接等内容,确保平台的安全性、性能和功能完整性。通过详细指导,帮助开发者快速搭建稳定可靠的圈子社交平台。
|
2月前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
174 3
|
4月前
|
监控 JavaScript 前端开发
前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。
|
4月前
|
前端开发 小程序 Java
java基础:map遍历使用;java使用 Patten 和Matches 进行正则匹配;后端传到前端展示图片三种情况,并保存到手机
这篇文章介绍了Java中Map的遍历方法、使用Pattern和matches进行正则表达式匹配,以及后端向前端传输图片并保存到手机的三种情况。
49 1
|
4月前
|
存储 前端开发 Java
验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
本文介绍了使用Kaptcha插件在SpringBoot项目中实现验证码的生成和验证,包括后端生成验证码、前端展示以及通过session进行验证码校验的完整前后端代码和配置过程。
561 0
验证码案例 —— Kaptcha 插件介绍 后端生成验证码,前端展示并进行session验证(带完整前后端源码)
|
4月前
|
前端开发 JavaScript Java
导出excel的两个方式:前端vue+XLSX 导出excel,vue+后端POI 导出excel,并进行分析、比较
这篇文章介绍了使用前端Vue框架结合XLSX库和后端结合Apache POI库导出Excel文件的两种方法,并对比分析了它们的优缺点。
1535 0
|
4月前
|
前端开发 JavaScript 小程序
前端uni开发后端用PHP的圈子系统该 如何做源码?
圈子系统系统基于TP6+Uni-app框架开发;客户移动端采用uni-app开发,管理后台TH6开发。系统支持微信公众号端、微信小程序端、H5端、PC端多端账号同步,可快速打包生成APP
|
4月前
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
|
2月前
|
存储 缓存 负载均衡
后端开发中的性能优化策略
本文将探讨几种常见的后端性能优化策略,包括代码层面的优化、数据库查询优化、缓存机制的应用以及负载均衡的实现。通过这些方法,开发者可以显著提升系统的响应速度和处理能力,从而提供更好的用户体验。
91 6

热门文章

最新文章

  • 1
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 2
    【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 3
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 4
    详解智能编码在前端研发的创新应用
  • 5
    巧用通义灵码,提升前端研发效率
  • 6
    【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
  • 7
    智能编码在前端研发的创新应用
  • 8
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 9
    抛弃node和vscode,如何用记事本开发出一个完整的vue前端项目
  • 10
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡