zoukankan      html  css  js  c++  java
  • SpringBoot实现下载文件以及前台应当如何对接

    SpringBoot实现文件下载以及前台对接方案

    文件的下载返回:

    这里用了一个ResponseEntity实体进行数据返回(当时就是不知道用什么对象返回文件,所以很恶心)。

    请求头使用Content-Disposition,fileName标记返回时的文件名称;
    ContentType使用octer-stream;
    ContentLength...可以选择不填,长度如果填错了会报错
    Body,返回文件的InputStream流

        fun downloadFile(@RequestBody fileId: Int): ResponseEntity<InputStreamResource> {
    
            val dest = fileService.getDownloadFile(fileId)
    
            return ResponseEntity.ok()
                    .header("Content-Disposition", "attachment;filename=" + dest.name)
                    .contentType(MediaType.parseMediaType("application/octet-stream"))
                    .contentLength(dest.length())
                    .body(InputStreamResource(dest.inputStream()))
        }
    

    当然,我还看到了一种字节流的下载方式,也挺有趣的,但是用了之后好像出了点问题,就没用了(可行,但是数据不对)。

    文件接收(百度用的一套代码)

        let filename = new Date().getTime().toString() + '.zip'
        let blob = new Blob([await downloadFile(res.data.data).data], { type: 'application/force-download' }) // 接收的是blob,若接收的是文件流,需要转化一下
        if (typeof window.chrome !== 'undefined') {
            // Chrome version
            let link = document.createElement('a')
            link.href = window.URL.createObjectURL(blob)
            link.download = filename
            link.click()
    
            // console.log(link)
        } else if (typeof window.navigator.msSaveBlob !== 'undefined') {
            // IE version
            let blob = new Blob([data], { type: 'application/force-download' })
            window.navigator.msSaveBlob(blob, filename)
        } else {
            // Firefox version
            let file = new File([data], filename, { type: 'application/force-download' })
            window.open(URL.createObjectURL(file))
        }
    

    虽然做出来了,但是很多地方都不完美,我遇到了一堆非常恶心的事情:
    因为这个是一个接口请求,只有请求完全结束(文件已经被下载下来之后),下载的文件才会突然显示。
    这并不符合我的预期,也是一个非常糟糕的交互。

    结局思路:

    1. 创建文件链接
    2. 开放文件下载接口,靠token和filepath进行下载

    Q&A

    为什么要写这篇文章

    • 作为一条孤龙来说,所有的解决方案都是自己去一点点翻查的。然后,网上居然一点类似的文章都没有!!

    参考文章&视频

    适用人群:一些和我一样不喜欢走按部就班的学习路径,选择自学,且只看目录的人们。。。


    后来用了接口的形式实现了不跳转界面的下载(瞬间跳转一下,然后自动关上的那种,我有一个可以优化的思路,无需跳转的,等下次完成了断点下载功能的时候一起更新了)

  • 相关阅读:
    Render Props
    react16新特性
    typescript
    calc
    类数组
    promise fullfill状态时 value是一个promise,那么此promise.then()里面收到的是什么
    M个同样的苹果放N个同样的盘子,允许有盘子空着, 问有多少种放法?
    history
    js创建二维数组
    钉钉-E应用开发初体验(企业内部应用)
  • 原文地址:https://www.cnblogs.com/Arunoido/p/14824268.html
Copyright © 2011-2022 走看看