vue js 移动端 pc 端 下载文件(文件流格式)PDF png xls 等格式通用!!!详细讲解、注释加代码

多文件pc端 移动端web下载 js+vue 实现

问题
① 后端返回值是文件流
② 移动端点击无效
③ 多种类型的文件下载 pdf png doc xls 等
④ pc端,安卓端,苹果端
⑤ 无状态码,如何判断是文件流还是传失败了

思路:
① 请求后端获取文件流
② 将文件流转换为blob链接
③ blob链接转化时要注意添加mime类型
(移动端不加此步会导致下载失效)
④ js创建一个a标签,并触发click点击下载

整体代码放在后面,新手试错,有问题请友善交流

效果:
pc端:


image.png

安卓端(不同的浏览器效果不同):


image.png

苹果端:
直接会新跳转一个页面进行预览,此处未截图

一、首先介绍mime

浏览器通常使用MIME类型(而不是文件扩展名)来确定如何处理URL,因此Web服务器在响应头中添加正确的MIME类型非常重要。如果配置不正确,浏览器可能会曲解文件内容,网站将无法正常工作,并且下载的文件也会被错误处理。
详细介绍以及类型见mdn
链接: MIME


image.png
二、文件流转blob链接

所谓的文件流就是后端直接把图片或者其他文件通过流的形式发送给前端(后端也可能发送文件链接,视具体情况而定)
文件流形式

此处因为后端直接传的文件流,没有传状态码,所以视情况更改代码

let content = data;//arraybuffer类型数据
          let resBlob = new Blob([content]);
          let reader = new FileReader();
          reader.readAsText(resBlob, 'utf-8');
          reader.onload = () => {
            try { // 判断是否可以转化为json格式,可以就说明不是文件流,错误返回值
              let res = JSON.parse(reader.result);
              console.log(res);
              this.$message.destroy();
              this.$message.error(res.message);
            } catch { // 报错说明不能转化为json,是文件流,下载文件
              console.log('res status', data);
              // let blob = new Blob([data]); // 原 此种方式在pc端可以下载,但是手机端不行
              let blob = new Blob([data], {
                'type': fileTypeMime
              }); //
              const blobUrl = window.URL.createObjectURL(blob);
              const a = document.createElement('a');
              a.style.display = 'none';
              a.download = fileName;
              a.href = blobUrl;
              a.click();
            }
          };
三、文件下载

通过js生成一个a链接节点,绑定文件下载链接,然后触发a的click事件
download是文件名字
href链接绑定blob上文转换的blob链接(移动端下载时,blob链接要加上mime类型,pc端可加可不加)

const a = document.createElement('a');
              a.style.display = 'none';
              a.download = fileName;
              a.href = blobUrl;
              a.click();

四、完整代码

getFileById() {
let params = {}; // 此处为向后端请求的参数
let fileName = ''; // 此处为下载的文件名字,包括格式后缀,如 test.jpg
let url = ''; // 此处为请求链接
let fileTypeMime = ''; // 文件mime类型

     // 个人赋值
    params = { taskCommonId: this.commonId };
    fileName = this.fileUrl;
    url = `${window._CONFIG['domianURL']}trial/task/plan/common/getFileByTaskCommonId`;
    let suffix = fileName.split(); // split后获得文件后缀
    suffix = suffix[suffix.length-1];
    switch (suffix) { // switch获取后缀对应的mime 可参考上文链接
      case 'png': fileTypeMime = 'image/png'; break;
      case 'doc': fileTypeMime = 'application/msword'; break;
      case 'docx': fileTypeMime = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; break;
      case 'jpg': case 'jpeg': fileTypeMime = 'image/jpeg'; break;
      case 'gif': fileTypeMime = 'image/gif'; break;
      case 'svg': fileTypeMime = 'image/svg+xml'; break;
      case 'tif': case 'tiff': fileTypeMime = 'image/tiff'; break;
      case 'txt': fileTypeMime = 'text/plain'; break;
      case 'ppt': fileTypeMime = 'application/vnd.ms-powerpoint'; break;
      case 'pptx': fileTypeMime = 'application/vnd.openxmlformats-officedocument.presentationml.presentation'; break;
      case 'xls': fileTypeMime = 'application/vnd.ms-excel'; break;
      case 'xlsx': fileTypeMime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; break;
      case 'zip': fileTypeMime = 'application/zip'; break;
      case '7z': fileTypeMime = 'application/x-7z-compressed'; break;
    }

    this.$http({
      url: url,
      method: 'get',
      responseType: 'arraybuffer',   //一定要设置响应类型,否则文件会是空白
      params: params,
    }).then((data) => {
      let content = data;//arraybuffer类型数据
      let resBlob = new Blob([content]);
      let reader = new FileReader();
      reader.readAsText(resBlob, 'utf-8');
      reader.onload = () => {
        try { // 判断是否可以转化为json格式,可以就说明不是文件流,错误返回值
          let res = JSON.parse(reader.result);
          console.log(res);
          this.$message.destroy();
          this.$message.error(res.message);
        } catch { // 报错说明不能转化为json,是文件流,下载文件
          console.log('res status', data);
          // let blob = new Blob([data]); // 原 此种方式在pc端可以下载,但是手机端不行
          let blob = new Blob([data], {
            'type': fileTypeMime
          }); //
          const blobUrl = window.URL.createObjectURL(blob);
          const a = document.createElement('a');
          a.style.display = 'none';
          a.download = fileName;
          a.href = blobUrl;
          a.click();
        }
      };
    });
  },

————————————————
版权声明:本文为CSDN博主「chestnut栗子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37235616/article/details/117965383

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容