前端文件下载的方式

简介: 【10月更文挑战第5天】

前端下载有两类,一类是直接让浏览器接管的(点击a链接触发),另一类是先在内存里下载好(blob),然后调用浏览器的保存。

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.FileInfo
    err := 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 = url
  a.download = filename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  window.URL.revokeObjectURL(url) // 释放blob对象
}
目录
相关文章
|
前端开发 API 对象存储
FileSaver.js源码学习,纯前端实现文件下载
FileSaver.js源码学习,纯前端实现文件下载
|
2月前
|
前端开发
前端base64转Blob,Blob转文件下载
前端将base64字符串转换为Blob对象,再将Blob对象转换为文件并实现下载。包括处理数据URL和纯base64字符串的情况,并提供了一个辅助函数用于转换。
58 2
|
5月前
|
存储 缓存 前端开发
全面解析:前端超大文件下载的关键技巧与优化策略
全面解析:前端超大文件下载的关键技巧与优化策略
254 1
全面解析:前端超大文件下载的关键技巧与优化策略
|
6月前
|
JSON JavaScript 前端开发
vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户
vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户
|
前端开发
前端常规关于网页文件下载的问题
前端常规关于网页文件下载的问题
63 0
|
XML 存储 移动开发
前端文件下载的正确打开方式
前端涉及到的文件下载还是很多应用场景的,那么前端文件下载有多少种方式呢?每种方式有什么优缺点呢?下面就来一一介绍。
167 0
|
前端开发
#yyds干货盘点 【React工作记录二十】前端常规关于网页文件下载的问题
#yyds干货盘点 【React工作记录二十】前端常规关于网页文件下载的问题
97 0
|
移动开发 前端开发 JavaScript
前端实现PDF文件下载的两种方式
前端实现PDF文件下载的两种方式
2347 0
前端实现PDF文件下载的两种方式
|
存储 缓存 前端开发
|
前端开发 应用服务中间件 nginx
常用前端文件下载方法
经常在项目中会遇到需要下载文件的需求,根据不同的需求和项目实现情况,通常有以下几种做法。
常用前端文件下载方法