0


前端实现文件下载常用几种方式

项目中前端下载一般分为两种情况:

  1. 后端直接提供一个文件地址,通过浏览器打开就可以下载。
  2. 需要发送请求,后端返回二进制流数据,前端解析流数据,生成URL实现下载。

前端对应的实质是a标签和

Blob

文件下载,这两者的区别:

  1. a标签:txt、png、jpg、gif等文件,是不提供直接下载,有兼容性问题,特别是IE。
  2. blob:利用 Blob对象可以将文件流转化成 Blob二进制对象。该对象兼容性良好,适用于需要动态生成或处理非同源文件的情况。‌通过URL.createObjectURL()方法将Blob对象转换为一个临时的URL下载。

blob对象

Blob对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成

ReadableStream

来用于数据操作。Blob对象是html5新增的对象,它的作用是用来存储二进制数据的,比如图片、视频、音频等,

属性

  • size:只读属性,Blob中的字节数。
  • type:只读属性,表示Blob存放的媒体类型,图片、视频、文本文件等等。 它的使用方法如下:
const blob =newBlob([],{type:''});

URL.createObjectURL

URL.createObjectURL()

静态方法会创建一个

DOMString

,其中包含一个表示参数中给出的对象的

URL

。这个

URL

的生命周期和创建它的窗口中的

document

绑定。这个新的

URL

对象表示指定的

File

对象或

Blob

对象。
当我们的

document

被销毁后,这个

URL

就会失效,所以我们需要在合适的时机销毁它。

简单说这个方法用来创建一个

url

的,它的作用是把一个

blob

对象转换成一个

url

,这个

url

可以用来下载文件,也可以用来预览文件。

// 创建下载的链接
const url = URL.createObjectURL(blob);
// 释放掉blob对象
URL.revokeObjectURL(url);

传统a标签下载

const a = document.createElement('a');// 创建a标签
a.style ='display: none';
a.download = filename'';// 设置下载文件名
a.href = url;// 设置下载地址
document.body.appendChild(a);
a.click();// 触发a标签的click事件
document.body.removeChild(a);

这种方式无法解决浏览器可识别文件直接打开的问题,但是 HTML5 新属性 download 属性会解决这个问题。

a标签 + download属性

URL

是同源(同域名、同协议、同端口号)时,这种情况用 a标签加download属性的方式即可,download属性指示浏览器该下载而不是打开该文件,同时该属性值即下载时的文件名;

<ahref="path/to/file.jpg"download='file.jpg'>点击下载图片</a>
const a = document.createElement('a');// 创建a标签const e = document.createEvent('MouseEvents');// 创建鼠标事件对象
e.initEvent('click',false,false);// 初始化事件对象
a.href = url;// 设置下载地址
a.download = filename ||'';// 设置下载文件名
a.dispatchEvent(e);

因为a标签下载只能下载同源的文件,如果是跨域的文件,这里包括图片、音视频等媒体文件,都是预览,也无法下载

fetch发送请求

  1. 通过原生fetch请求,动态生成一个a标签实现文件下载。
  2. res.blob()该方法是Fetch API的response对象方法,该方法将后端返回的文件流转换为返回blob的Promise;blob(Binary Large Object)是一个二进制类型的对象,记录了原始数据信息。
  3. URL.createObjectURL(blob)该方法的返回值可以理解为一个指向传入参数对象的url可以通过该url访问参数传入的对象。
// 将url转成blob地址fetch(url).then(res=> res.blob()).then(blob=>{const a = document.createElement('a');// 将链接地址字符内容转变成blob地址
        a.href =URL.createObjectURL(blob);
        a.download = filename;// 下载文件的名字
        document.body.appendChild(a);
        a.click();// 下载完成后 清除占用的缓存资源
        window.URL.revokeObjectURL(a.href);
        document.body.removeChild(a);});
  • 该方法需要注意的是,即便传入同一个对象作为参数,每次返回的url对象都是不同的。
  • 该url对象保存在内存中,只有在当前文档(document)被卸载时才会被清除,因此为了更好的性能,需要通过URL.revokeObjectURL(blobUrl)主动释放。

XMLHttpRequest

XMLHttpRequest(‌简称XHR)‌是一个用于创建服务器之间通信的Web API。‌在下载文件时,‌可以通过设置

responseType

blob

来接收二进制数据。‌这种方法适用于需要从服务器获取文件流并进行下载的场景。‌与Blob类似,‌XHR也可以用于动态生成文件并触发下载,‌但它在处理异步请求和数据传输方面提供了更多的灵活性。‌

  1. 可通过xhr.setRequestHeader设置请求头参数。
  2. 可通过xhr.getResponseHeader(‘content-disposition’)获取头部参数。
let xhr =newXMLHttpRequest();// GET请求,downloadURL请求路径url,async(是否异步)
xhr.open('GET', downloadURL,true);// 设置请求头参数的方式,如果没有可忽略此行代码
xhr.setRequestHeader("Token",'Bearer '+getStorage().token);// token// 设置响应类型为 blob
xhr.responseType ='blob';// 关键部分
xhr.onload=function(){//如果请求执行成功if(this.status ===200){// 下载文件const blob =newBlob(this.response);const href = window.URL.createObjectURL(blob);// 创建下载的链接const a = document.createElement('a');
        a.href = href;
        a.download = fileName;// 下载文件名
        document.body.appendChild(a);
        a.click();// 点击下载
        document.body.removeChild(a);// 下载完成移除元素
        window.URL.revokeObjectURL(href);// 释放掉blob对象// 可通过xhr.getResponseHeader('content-disposition')头部参数,文件名等// let headerParams = xhr.getResponseHeader('content-disposition')?.split(";") || [];}};// 发送请求
xhr.send();
xhr.onreadystatechange=function(){if(xhr.readyState ===4&& xhr.status ===200){// 成功后操作 }};

axios请求方式

axios({method: method ||'post',
    url,responseType:'blob',headers:{'Content-Type':'application/json; charset=utf-8'// 可在此处添加请求参数token:'token值'}data:JSON.stringify(params)}).then(res=>{if(res){const blob =newBlob(res);const url = window.URL.createObjectURL(blob)const a = document.createElement('a')
        a.style.display ='none'
        a.href = href;
        a.download = fileName;// 下载文件名
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link);// 下载完成移除元素
        window.URL.revokeObjectURL(url);// 释放掉blob对象}else{
        message.error('下载失败')return;}})

无论是通过

fetch

XMLHttpRequest

axios

请求,处理逻辑都是请求成功后,拿到相应的

response

,这个

response

就是我们要下载的内容,通过将它转成

blob

对象,通过

URL.createObjectURL

创建下载

URL

,通过a标签实现下载。

标签: 前端

本文转载自: https://blog.csdn.net/weixin_44242600/article/details/141057805
版权归原作者 zj靖 所有, 如有侵权,请联系我们删除。

“前端实现文件下载常用几种方式”的评论:

还没有评论