当前位置: 首页 > news >正文

【前端】下载文件方法

1.window.open

我最初使用的方法就是这个,只要提供了文件的服务器地址,使用window.open也就是在新窗口打开,这时浏览器会自动执行下载。

2.a标签

其实window.open和a标签是一样的,只是a标签是要用户点击触发,而window.open可以主动触发

后端如果设置了Content-Disposition ,那么不需要download属性也能下载。而且后端还可以设置文件名。

<a href="https:xxx.mp4" download="test">下载文件</a>

3.xhr(axios)下载

这个时候,请求发送的时候需要注明responseType = "blob",如果没有设置的情况下,new Blob的时候需要传入第二个参数。比如new Blob([res], { type: xhr.getResponseHeader("Content-Type") });

只是这时后端就没法通过body报错了。只能通过状态码和响应头来传递信息了。

最后我还是选择用json来传递信息,设置这个responseType: 'blob',以后,返回值会被转为blob,这时我们log可以看到type,是application/json的情况就是报错的情形。然后我们转化一遍json可以拿到报错信息,其实也可以把这个逻辑加到axios拦截器里面

export const DOWNLOAD_ITEM = async (data: FileItem): Promise<any> => {const res: Blob = await request.post(`${PROXY_SUFFIX}/downloadItem`, data, {responseType: 'blob',})// json的情况说明是报错if (res.type !== 'application/json') {downloadFile(res, data.name)} else {const r = await res.text()message.error(JSON.parse(r)?.msg)}
}

这边我后端用的是golang的gin框架

返回文件流调用c.File,文件类型不用传,c.Header("Content-Disposition", "attachment; filename="+req.Name)这个设置可以返回文件名。

func (f *FileListAPI) DownloadItem(c *gin.Context) {var req response.FileInfoerr := c.ShouldBindJSON(&req)if err != nil {response.FailWithMessage(err.Error(), c)return}if req.Path == "" {response.FailWithMessage("路径不能为空", c)return}if req.IsFolder {response.FailWithMessage("路径不能为文件夹", c)return} else {c.Header("Content-Disposition", "attachment; filename="+req.Name)// c.Header("Content-Transfer-Encoding", "binary")// c.Header("Content-Type", "application/octet-stream")c.File(req.Path)}fmt.Println("req", req)}

下面是blob对象下载的逻辑,使用createObjectURL转换为url,然后绑到a链接上,通过点击a链接的方式触发下载。

/*** 使用bolb方式下载* @param res* @param filename* @returns*/
export function downloadFile(res: Blob, filename: string) {const url = window.URL.createObjectURL(new Blob([res]))const a = document.createElement('a')a.style.display = 'none'a.href = urla.download = filenamedocument.body.appendChild(a)a.click()document.body.removeChild(a)window.URL.revokeObjectURL(url) // 释放blob对象
}
http://www.lryc.cn/news/278141.html

相关文章:

  • 虚幻UE 材质-纹理 1
  • 回归预测 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量回归预测
  • 【AWS系列】巧用 G5g 畅游Android流媒体游戏
  • GNSS数据及产品下载地址(FTP/HTTP)
  • 【STM32】STM32学习笔记-DMA数据转运+AD多通道(24)
  • 即时设计:设计流程图,让您的设计稿更具条理和逻辑
  • 单个独立按键控制直流电机开关
  • 前端插件库-VUE3 使用 JSEncrypt 插件
  • Neo4j备份
  • 【LangChain学习之旅】—(5) 提示工程(上):用少样本FewShotTemplate和ExampleSelector创建应景文案
  • Python从入门到精通秘籍一
  • 【IC设计】移位寄存器
  • 【Flutter 开发实战】Dart 基础篇:最基本的语法内容
  • 中国光伏展
  • Nacos的统一配置管理
  • SpringBoot项目docker镜像生成
  • JDBC初体验(二)——增、删、改、查
  • Eva.js是什么(互动小游戏开发)
  • 监听 beforeunload 事件,阻止页面刷新导致的信息丢失
  • Java 常见缓存详解以及解决方案
  • Golang 交叉编译之一文详解
  • 最新ThinkPHP版本实现证书查询系统,实现批量数据导入,自动生成电子证书
  • windows安装运行Apache James(基于spring的版本)
  • Elasticsearch 基本概念:快速入门指南【记录】
  • 【JVM 基础】类字节码详解
  • 【算法】基础算法001之双指针
  • [力扣 Hot100]Day2 字母异位词分组
  • 记一次 easyswoole 热重载失效复盘 grpc扩展惹的祸
  • 存储过程从表中获取数据库名称
  • .NET 反射的介绍和简单应用