方法一:a标签的download
采用原生创建dom节点的方法,注册a标签,把文件的地址放入 a标签的href里面。再通过js触发事件。
<div onClick={()=>{this.handleDownLoad(record)}}>下载</div>handleDownLoad = async record =>{let aEle = document.getElementById('aElement');// 创建dom节点if(!aEle){try{aEle = document.creatElement('<a name="aElement">');}catch(e){aEle = document.createElement('a')}}// 把创建的dom节点挂载到dom树上document.body.appendChild(aEle);// 隐藏a标签aEle.style.display = 'none';aEle.href = 'https://xxxxx.com';aEle.download = '文件名称';aEle.click();}
方法二:form表单提交
为一个下载按钮添加click事件,点击时动态生成一个表单,利用表单提交的功能来实现文件的下载
/*** 下载文件* @param {String} path - 请求的地址* @param {String} fileName - 文件名*/function downloadFile (downloadUrl, fileName) {// 创建表单const formObj = document.createElement('form');formObj.action = downloadUrl;formObj.method = 'get';formObj.style.display = 'none';// 创建input,主要是起传参作用const formItem = document.createElement('input');formItem.value = fileName; // 传参的值formItem.name = 'fileName'; // 传参的字段名// 插入到网页中formObj.appendChild(formItem);document.body.appendChild(formObj);formObj.submit(); // 发送请求document.body.removeChild(formObj); // 发送完清除掉}
方法三:open或location.href
本质上和a标签访问下载链接一样
window.open('downloadFile.zip');location.href = 'downloadFile.zip';
方法四:Blob对象
调用api,将文件流转为Blob二进制对象, :::danger 注:IE10以下不支持。 ::: 思路: 发请求获取二进制数据,转化为Blob对象,利用URL.createObjectUrl生成url地址,赋值在a标签的href属性上,结合download进行下载。
/*** 下载文件* @param {String} path - 下载地址/下载请求地址。* @param {String} name - 下载文件的名字/重命名(考虑到兼容性问题,最好加上后缀名)*/downloadFile (path, name) {const xhr = new XMLHttpRequest();xhr.open('get', path);xhr.responseType = 'blob';xhr.send();xhr.onload = function () {if (this.status === 200 || this.status === 304) {// 如果是IE10及以上,不支持download属性,采用msSaveOrOpenBlob方法,但是IE10以下也不支持msSaveOrOpenBlobif ('msSaveOrOpenBlob' in navigator) {navigator.msSaveOrOpenBlob(this.response, name);return;}/*如果发送请求时不设置xhr.responseType = 'blob',默认ajax请求会返回DOMString类型的数据,即字符串。此时需要使用两处注释的代码,对返回的文本转化为Blob对象,然后创建blob url,此时需要注释掉原本的const url = URL.createObjectURL(target.response)。*//*const blob = new Blob([this.response], { type: xhr.getResponseHeader('Content-Type') });const url = URL.createObjectURL(blob);*/const url = URL.createObjectURL(this.response); // 使用上面则注释此行const a = document.createElement('a');a.style.display = 'none';a.href = url;a.download = name;document.body.appendChild(a);a.click();document.body.removeChild(a);URL.revokeObjectURL(url);}};}
// 上面方法本地测试有时会有跨域问题,下面使用axios重写一下// 已经配置好proxydownloadFile (path, name) {axios.get({url: path,method: 'get'}).then(res => {const blob = new Blob([res.data], { type: res.headers['content-type'] });const url = URL.createObjectURL(blob);const a = document.createElement('a');a.style.display = 'none';a.href = url;a.download = name;document.body.appendChild(a);a.click();document.body.removeChild(a);URL.revokeObjectURL(url);})}
该方法不能缺少a标签的download属性的设置。
因为发请求时已设置返回数据类型为Blob类型(xhr.responseType = ‘blob’),所以target.response就是一个Blob对象,打印出来会看到两个属性size和type。虽然type属性已指定了文件的类型,但是为了稳妥起见,还是在download属性值里指定后缀名,如Firefox不指定下载下来的文件就会不识别类型。
方法五:利用Base64
/*** 下载文件* @param {String} path - 下载地址/下载请求地址。* @param {String} name - 下载文件的名字(考虑到兼容性问题,最好加上后缀名)*/downloadFile (path, name) {const xhr = new XMLHttpRequest();xhr.open('get', path);xhr.responseType = 'blob';xhr.send();xhr.onload = function () {if (this.status === 200 || this.status === 304) {const fileReader = new FileReader();fileReader.readAsDataURL(this.response);fileReader.onload = function () {const a = document.createElement('a');a.style.display = 'none';a.href = this.result;a.download = name;document.body.appendChild(a);a.click();document.body.removeChild(a);};}};}
