当前位置: 首页 > news >正文

JS-文件下载,实现在ios也是下载 而不是预览,

需求

通过A链接的方式,把从后台获取到的文件下载到本地,实现在移动端,PC端都能下载

问题

通过ajax请求后端生成的文件流之后,创建BLOB文件进行下载,在PC端和移动安卓端都可以实现下载到本地和对应的手机,而在IOS端的话,是直接预览对应的blob文件地址 而不是下载对应的文件流,解决在IOS上也能实现下载(仅限Safari浏览器)

步骤

1.通过request,responseType的值为 'arraybuffer',请求对应的文件流

uni.request({...handleRes,responseType: 'arraybuffer',success(res) {// console.log(res, '返回数据');// 这是返回的文件流const file = res.data;},fail() {uni.hideLoading();}})

2.通过将文件流转成blob对象

let blob = null;if (headerDis.indexOf(tyepList.toString()) != -1) {blob = new Blob([file], {type: 'application/octet-stream;charset=UTF-8',})} else {blob = new Blob([file], {type: headerInfo['content-type'] ||'application/octet-stream;charset=UTF-8',})}

3.通过创建A链接,通过download属性进行下载

async linkTodownloadFile(blob, fName) {if (window.navigator.msSaveOrOpenBlob) {window.navigator.msSaveBlob(blob, fName);return false;}const url = window.URL.createObjectURL(blob)const link = document.createElement('a')link.style.display = 'none'link.href = url;link.setAttribute('download', fName)document.body.appendChild(link)if (document.all) {link.click();} else {// 兼容 Firfoxconst evt = document.createEvent('MouseEvents');evt.initEvent('click', true, true);link.dispatchEvent(evt);}document.body.removeChild(link) // 下载完成移除元素window.URL.revokeObjectURL(url);uni.hideLoading();common.toast(107)}

注意:这里需要主要的在IOS端如果自定义blob的type的话  download属性就只加文件名 而不需要后缀,会形成双重后缀.而且如果类型为steam的话就会是预览  而设置成steam的话就会直接下载文件,也就是第二步做的判断原因

4.完整的代码

uni.request({url : 'xxx',responseType: 'arraybuffer',success(res) {// console.log(res, '返回数据');const file = res.data;const headerInfo = res.header;/** 获取文件名称 */let fName = '';/** 判断是否为可自定义类型还是默认 */const tyepList = ['pdf'];const headerDis = headerInfo['content-disposition'];if (headerDis) {const requestFileInfo = headerDis.split(';')[1];if (store.state.app.SYSTEM_INFO.platform == 'ios') {if (headerDis.indexOf(tyepList.toString()) != -1) {fName = requestFileInfo;} else {fName = requestFileInfo.split('.')[0];}} else {fName = requestFileInfo;}} else {/** 判断文件是否有类型,没有就拿效应头 */const fType = file.type || headerInfo['content-type'].split(';')[0];for (const key in fileTypeConfig) {if (fileTypeConfig[key].indexOf(fType) != -1) {if (store.state.app.SYSTEM_INFO.platform == 'ios') {fName = `${fileName}`;} else {fName = `${fileName}.${key}`;}break}}}/** 开始下载 */let blob = null;if (headerDis.indexOf(tyepList.toString()) != -1) {blob = new Blob([file], {type: 'application/octet-stream;charset=UTF-8',})} else {blob = new Blob([file], {type: headerInfo['content-type'] ||'application/octet-stream;charset=UTF-8',})}/** 判断是否为JSON 做逻辑处理 */if (fName.indexOf('json') != -1) {//通过FileReader读取数据const reader = new FileReader();// reader.readAsBinaryString(blob);reader.readAsText(blob, 'utf8');reader.onload = function() {var content = JSON.parse(this.result); //这个就是解析出来的数据if (content.code == 200) {// common.toast(fName);that.linkTodownloadFile(blob, fName);resolve();} else {isLoading && uni.hideLoading();common.toast(content.msg || 400);}}} else {// common.toast(fName);that.linkTodownloadFile(blob, fName);resolve();}},fail() {uni.hideLoading();common.toast(108)reject();}})

5.附件 fileTypeConfig的内容

export default {xls: 'application/vnd.ms-excel',xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',csv: 'text/csv',doc: 'application/msword',docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',pdf: 'application/pdf',ppt: 'application/vnd.ms-powerpoint',pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',png: 'image/png',gif: 'image/gif',jpeg: 'image/jpeg',jpg: 'image/jpeg',mp3: 'audio/mpeg',aac: 'audio/aac',html: 'text/html',css: 'text/css',js: 'text/javascript',json: 'application/json',abw: 'application/x-abiword',arc: 'application/x-freearc',avi: 'video/x-msvideo',azw: 'application/vnd.amazon.ebook',bin: 'application/octet-stream',bmp: 'image/bmp',bz: 'application/x-bzip',bz2: 'application/x-bzip2',csh: 'application/x-csh',eot: 'application/vnd.ms-fontobject',epub: 'application/epub+zip',htm: 'text/html',ico: 'image/vnd.microsoft.icon',ics: 'text/calendar',jar: 'application/java-archive',jsonld: 'application/ld+json',mid: 'audio/midi audio/x-midi',midi: 'audio/midi audio/x-midi',mjs: 'text/javascript',mpeg: 'video/mpeg',mpkg: 'application/vnd.apple.installer+xml',odp: 'application/vnd.oasis.opendocument.presentation',ods: 'application/vnd.oasis.opendocument.spreadsheet',odt: 'application/vnd.oasis.opendocument.text',oga: 'audio/ogg',ogv: 'video/ogg',ogx: 'application/ogg',otf: 'font/otf',rar: 'application/x-rar-compressed',rtf: 'application/rtf',sh: 'application/x-sh',svg: 'image/svg+xml',swf: 'application/x-shockwave-flash',tar: 'application/x-tar',tif: 'image/tiff',tiff: 'image/tiff',ttf: 'font/ttf',txt: 'text/plain',vsd: 'application/vnd.visio',wav: 'audio/wav',weba: 'audio/webm',webm: 'video/webm',webp: 'image/webp',woff: 'font/woff',woff2: 'font/woff2',xhtml: 'application/xhtml+xml',xml: 'text/xml',xul: 'application/vnd.mozilla.xul+xml',zip: 'application/zip,application/x-zip-compressed',}

http://www.lryc.cn/news/212029.html

相关文章:

  • Leetcode.275 H 指数 II
  • 代码随想录Day40-单调栈:力扣第496e、503m、42h、84h题
  • Git窗口打开vim后如何退出编辑(IDEA/Goland等编辑器)
  • 【CSDN 每日一练 ★★☆】【二叉树/BSF】二叉树的层序遍历
  • Golang | Zinx学习笔记(一)
  • 【Java 进阶篇】在Java Web应用中获取ServletContext对象详解
  • 负债6W,依靠这个项目副业6个月还清欠款,还多存了10W+
  • 快速了解ClickHouse!
  • PythonWEB
  • 【工具问题】IDEA每次关闭的时候都会弹框显示closing project,然后弹框持续很久就像卡住了
  • 从瀑布模式到水母模式:ChatGPT如何赋能软件研发全流程
  • 类变量/方法、main语法、代码块
  • [SHCTF 校外赛道] crypto
  • vue3从基础到入门(一)
  • 枚举类型 表示不同的 HTTP 状态码和相应的错误消息
  • SAP 使用cl_gui_timer自动刷新屏幕的用法详解 <转载>
  • golang中的Interface接口 类型断言、接口赋值、空接口的使用、接口嵌套
  • 使用设计模式省去大量的if-elsef分支
  • Tomcat安装与配置文件解读
  • 计算机网络重点概念整理-第一章 计算机网络概述【期末复习|考研复习】
  • Day 11 python学习笔记
  • HarmonyOS鸿蒙原生应用开发设计- 图标库
  • 微软bing大声朗读文档或网页卡顿老是中断,用离线的huihui就很流畅但没那么自然
  • Java VMTranslator Part I
  • ES6带来那些js新特性?
  • js数组深拷贝汇总
  • 错误 LNK1112 模块计算机类型“x64”与目标计算机类型“X86”冲突
  • java八股文(基础篇)
  • window系统修改rabbitmq 默认端口
  • 七人拼团模式:颠覆你的购物观念,499元产品让你赚翻天!