文件下载相关问题汇总

2022-01-26  本文已影响0人  Simple_Learn

前端使用 axios 下载文件

一般步骤如下:

前端解析数据流,主要使用 Blob 对象来进行接收

// 以之前的post请求举例
axios.post(url, {...someData}, {responseType: 'blob'})
    .then((res) => {
        const { data, headers } = res
        const fileName = headers['content-disposition'].replace(/\w+;filename=(.*)/, '$1')
        // 此处当返回json文件时需要先对data进行JSON.stringify处理,其他类型文件不用做处理
        //const blob = new Blob([JSON.stringify(data)], ...)
        const blob = new Blob([data], {type: headers['content-type']})
        let dom = document.createElement('a')
        let url = window.URL.createObjectURL(blob)
        dom.href = url
        dom.download = decodeURI(fileName)
        dom.style.display = 'none'
        document.body.appendChild(dom)
        dom.click()
        dom.parentNode.removeChild(dom)
        window.URL.revokeObjectURL(url)
    }).catch((err) => {})

Blob对象简要介绍

Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 Blob 的功能并将其扩展使其支持用户系统上的文件。

语法

const blob = new Blob( array, options ); 

参数说明

示例

const debug = {hello: "world"};
const blob = new Blob([JSON.stringify(debug, null, 2)],{type : 'application/json'});

URL.createObjectURL() 与 URL.revokeObjectURL()介绍

URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。相当于这个方法创建了一个传入对象的内存引用地址

createObjectURL语法

objectURL = URL.createObjectURL(object);

参数说明

返回值

URL.revokeObjectURL() 静态方法用来释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象。当你结束使用某个 URL 对象之后,应该通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。

你可以在 sourceopen 被处理之后的任何时候调用 revokeObjectURL()。这是因为 createObjectURL() 仅仅意味着将一个媒体元素的 src 属性关联到一个 MediaSource 对象上去。调用revokeObjectURL() 使这个潜在的对象回到原来的地方,允许平台在合适的时机进行垃圾收集

revokeObjectURL语法

window.URL.revokeObjectURL(objectURL);

参数说明

内存管理

在每次调用createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。浏览器会在文档退出的时候自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

比如下载文件实际运用

比如在某后台管理中希望将用户的几个配置信息导入到一个json文件当中供用户下载下来

代码实现如下:

const config = {
  name: 'lsqy',
  password: 'yourpassword',
  ak: 'XXXXXXXXXX',
  sk: 'XXXXXXXXXX'
}

const blobContent = new Blob(
  [JSON.stringify(config, null, 2)],
  {type : 'application/json'}
);

const blobUrl = window.URL.createObjectURL(blobContent)

downloadFileByBlob(blobUrl, 'config.json')

function downloadFileByBlob(blobUrl, filename) {
  const eleLink = document.createElement('a')
  eleLink.download = filename
  eleLink.style.display = 'none'
  eleLink.href = blobUrl
  // 触发点击
  document.body.appendChild(eleLink)
  eleLink.click()
  // 然后移除
  document.body.removeChild(eleLink)
}

执行上面的代码,我们可以得到一个config.json的文件,可以看到,其实很简单就实现了这个场景需求,当然这里是下载的json文件,下载其他的文件也是一样的道理,只是需要得到相应文件的blob数据,再结合相应的MIME类型即可;

兼容性方面目前主流浏览器都已支持,ie10以及以上也支持。

另外Blob结合URL. createObjectURL()URL.revokeObjectURL()还可以用在预览图片、预览PDF、视频链接防盗等多种场景中,大家可以发挥自己的想象力来进行实现.

图片的显示如下:

axios.post(url, {...someData}, {responseType: 'blob'})
    .then((res) => {
        const { data } = res
        const reader = new FileReader()
        reader.readAsDataURL(data)
        reader.onload = (ev) => {
            const img = new Image()
            img.src = ev.target.result
            document.body.appendChild(img)
        }
    }).catch((err) => {})

参考MDN

  1. https://developer.mozilla.org/zh-CN/docs/Web/API
    搜索关键字:responseType 、Blob 、createObjectURL、revokeObjectURL
  2. 使用axios如何下载文件
  3. axios获取文件流并下载文件
上一篇下一篇

猜你喜欢

热点阅读