当同一种实现原理可以完成不同需求任务的时候,我们却只知道通过需求的关键词去网上查找解决方案,却不知我们之前的实现另一种需求的方式方法也能同时应用到当前需求上来,这很大程度上跟自个的基础能力相关;基础不牢固,有病乱投医,是不是这个理?
axios({ method: 'get', params: { file_url: re.data_url, file_name: re.data_name }, url: `https:/xxx.com${url}`, // for example: http://dev-head-api.xht-kyy.com/downSkuFile?id=2196 // 堆代码 duidaima.com // 必须显式指明响应类型是一个Blob对象,这样生成二进制的数据, //才能通过window.URL.createObjectURL进行创建成功 responseType: 'blob', }).then((res) => { if (!res) { return } // 将blob对象转换为域名结合式的url let blobUrl = window.URL.createObjectURL(res.data) let link = document.createElement('a') document.body.appendChild(link) link.style.display = 'none' link.href = blobUrl // 设置a标签的下载属性,设置文件名及格式,后缀名最好让后端在数据格式中返回 link.download = 'xx.csv' // 自触发click事件 link.click() document.body.removeChild(link) window.URL.revokeObjectURL(blobUrl); })通过在body中增加个a标签,并立即执行点击事件,进行跳转访问url,get到的内容为blob文件下载。代码中提到设置a标签的下载属性,设置文件名及格式,后缀名最好让后端在数据格式中返回,那么后端返回的后缀和文件名该如何提取?
outImport (re) { this.$axios({ method: 'get', params: { file_url: re.data_url, file_name: re.data_name }, url: `https:/xxx.com${url}`, responseType: 'blob' }).then((res) => { console.log(res) let str = res.headers['content-disposition'] str = str.substr(str.indexOf('=') + 1, str.length) this.downloadFile(res.data, decodeURI(str)) }) }, downloadFile (blob, fileName) { if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(blob, fileName) } else { const link = document.createElement('a') const evt = document.createEvent('HTMLEvents') evt.initEvent('click', false, false) document.body.appendChild(link) link.href = URL.createObjectURL(blob) link.download = fileName link.style.display = 'none' link.click() document.body.removeChild(link) window.URL.revokeObjectURL(link.href) } },这里涉及到几个属性:
URL.createObjectURL(file)存在于当前doucment内,清除方式只有unload()事件或revokeObjectURL()手动清除 。
export const downloadMp3 = (filePath) => { fetch(filePath).then(res => res.blob()).then(blob => { const a = document.createElement('a'); document.body.appendChild(a) a.style.display = 'none' // 使用获取到的blob对象创建的url const url = window.URL.createObjectURL(blob); a.href = url; // 指定下载的文件名 a.download = '语音音频.mp3'; a.click(); document.body.removeChild(a) // 移除blob对象的url window.URL.revokeObjectURL(url); }); }这里涉及到fetch, 简要总结下fetch的使用(结合上述代码所使用的情况),也和方法一种axios的方法做一个简要的比较:
{ method: "GET",//请求方式 headers: {//定制http请求的标头 "Content-Type": "text/plain;charset=UTF-8" }, body: undefined,//post请求的数据体,因为此时为get请求,故为undefined referrer: "about:client", referrerPolicy: "no-referrer-when-downgrade",//用于设定fetch请求的referer标头 mode: "cors", //指定请求模式,此时为cors表示支持跨域请求 credentials: "same-origin",//发送cookie cache: "default",//指定如何处理缓存 redirect: "follow", integrity: "", keepalive: false, signal: undefined }而其链式调用方式:
fetch('网址') // 堆代码 duidaima.com // fetch()接收到的response是一个 Stream 对象 // response.json()是一个异步操作,取出所有内容,并将其转为 JSON 对象 .then(response => response.json()) .then(json => console.log(json))//获取到的json数据 .catch(err => console.log('Request Failed', err));
后续写一篇针对该方法的总结。
thumbnailView (item) { item.name = item.original_name const suffix = item.name.substring(item.name.lastIndexOf('.') + 1) if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'tiff', 'webp'].includes(suffix)) { this.preView(item) } else if (['xlsx', 'xls', 'doc', 'docx', 'ppt', 'pptx'].includes(suffix)) { this.viewNew(item, suffix) } else if (['pdf', 'PDF'].includes(suffix)) { this.viewNewPDF(item) } else { this.showConfirm(item) } }, preView (val) { this.$refs.imageView.open(val.file_name) }, preView2 (val) { this.$refs.imageView.open(val) }, viewNewPDF (item) { window.open(item.file_name, '_blank') }, showConfirm (item) { this.$confirm({ title: '提示', content: h => <div>该文件不支持预览、请下载后查阅</div>, okText: '下載文件', onOk: () => { saveAs(item.file_name, item.name) } }) }, viewNew (val, suffix) { window.open(`https://view.officeapps.live.com/op/view.aspx?src=${val.file_name}`, '_blank') },
import { saveAs } from 'file-saver'; saveAs(Blob/File/Url, optional DOMString filename, optional Object { autoBom }第一个参数支持三种类型,这也时下载文件的一个插件