微信公众号内下载pdf等文件,受微信所限制,安卓和IOS不同处理方式

时间:2025-04-25 07:29:28

前言:

IOS手机可以直接下载文件,但是需要后端设置Content-Disposition和Content-Type

安卓手机只能打开其他浏览器下载,(别问我怎么知道的,试出来的结果),所以跳转至中专页,让在默认浏览器打开

最新最优方法可以点击阅读,本篇文章可以直接略过

所需要的方法:

1:是否时微信浏览器环境

export const isWeChat = () => {
  var ua = ();
  // ('micromessenger')为真-微信端,如果为假,就是其他浏览器
  if (("micromessenger") > -1) {
    return true; // 是微信端
  } else {
    return false;
  }
};

2: 判断时安卓还是IOS

export const appSource = () => {
  const u = ;
  const isiOS = !!(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
  if (isiOS) {
    return "ios";
  } else {
    return "andriod";
  }
};

3:form表单方式下载文件

export const downloadform = url => {
  var form = ("form");
   = url;
   = "get";
   = "none";
  (form);
  ();
  (form);
};

使用方式

import { appSource, downloadform } from "@/utils/util";
downloadClick() {
	if (appSource() === "ios") {
	  downloadform(`${}/preHostilePdf/2022-02-21/`);
	} else {
	  // 安卓去中转页
	  this.$({
	    path: "/pdfView",
	    query: {
	      toLink: encodeURIComponent("/preHostilePdf/2022-02-21/")
	    }
	  });
	}
},

/pdfView 页面源码 (只针对安卓用户)

PopUp组件是引导层,引导用户点击右上角打开其他默认浏览器,代码就不贴这里了,每个公司都有每个公司的风格。
_loadFile是使用 预览pdf文件的,会在下个文章写,当然如果页面是空白也可以,或者是一段友好的提醒文字也可以。

<template>
  <div class="canvas-container">
    <div class="canvas" :class="scaleCount > 0 ? 'scroolBox' : ''" >
      <canvas v-for="page in pages" class="canvasDiv" : :key="page" ref="pdf"></canvas>
    </div>
    <div class="flexBox">
      <img @click="scaleD" class="big" src="@/assets/icon/" alt="" />
      <br />
      <img v-show="scaleCount === 0" class="small" src="@/assets/icon/" alt="" />
      <img v-show="scaleCount > 0" @click="scaleX" class="small" src="@/assets/icon/" alt="" />
    </div>
    <div class="bottom_box">
      <button @click="submit_btn()">
        下载
      </button>
    </div>
    <Pop-up ref="mPopUp">
      <div slot="popupContent">
        <div class="steerTop">
          <div class="steerArrowBox">
            <img class="steerArrow" src="@/assets/images/" />
          </div>
          <div class="steerWordingBox">
            <img class="steerWording" src="@/assets/images/" />
          </div>
        </div>
        <img class="steerImg" src="@/assets/images/" />
      </div>
    </Pop-up>
  </div>
</template>
<script>
import { _loadFile } from "@/utils/common";
import { isWeChat, downloadform } from "@/utils/util";
import PopUp from "components/component/PopUp";
export default {
  components: {
    PopUp
  },
  data() {
    return {
      pages: [],
      scaleCount: 0,
      scale: 1.1,
      imageUrl: "",
      toLink: ""
    };
  },
  mounted() {
    ();
  },
  methods: {
    initPage() {
       = decodeURIComponent(this.$);
      _loadFile.call(this,  + );
      this.submit_btn();
    },
    scaleD() {
      ++;
      this.$(item => {
        let widthTemp = ("px")[0];
        let heightTemp = ("px")[0];
         = parseInt(widthTemp) * parseFloat() + "px";
         = parseInt(heightTemp) * parseFloat() + "px";
      });
    },
    scaleX() {
      if ( == 0) {
        return;
      }
      this.$(item => {
        let widthTemp = ("px")[0];
        let heightTemp = ("px")[0];
         = parseInt(widthTemp) / parseFloat() + "px";
         = parseInt(heightTemp) / parseFloat() + "px";
      });
      --;
    },
    submit_btn() {
      if (isWeChat()) {
        // 内部浏览器弹出引导
        this.$ = true;
      } else {
        // 外部浏览器直接下载
        downloadform( + );
      }
    }
  }
};
</script>
<style lang="less" scoped>
.canvas-container {
  margin: 0 auto;
  iframe {
    width: 100%;
    height: calc(100vh - 4rem);
  }
  .canvas {
    width: 100%;
    height: calc(100vh - 2.8rem);
    overflow-x: hidden;
    overflow-y: auto;
    .canvasDiv {
      border-bottom: 1px solid #ccc;
    }
  }
  .scroolBox {
    overflow-x: auto !important;
    overflow-y: auto !important;
  }
  .flexBox {
    position: fixed;
    right: 0.2rem;
    top: 1.4rem;
    padding: 0.1rem;
    background-color: rgba(244, 244, 244, 0.6);
    border-radius: 0.4rem;
    overflow: hidden;
    .big {
      width: 0.58rem;
    }
    .small {
      width: 0.58rem;
    }
  }
  .bottom_box {
    padding: 0 0.48rem 0 0.48rem;
    height: 1.6rem;
    .note {
      font-size: 0.3rem;
      color: #999;
      word-wrap: break-word;
    }
    .btn-disable {
      opacity: 0.3;
    }
  }
  .steerTop {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    margin: auto;
    .steerArrowBox {
      margin-top: 2vw;
      padding: 2vw;
      text-align: right;
      .steerArrow {
        width: 20%;
        transform: rotateZ(342deg);
        animation: beat 1s linear infinite;
      }
    }
    @keyframes beat {
      0% {
        margin-top: 2vw;
      }
      50% {
        margin-top: 4vw;
      }
      100% {
        margin-top: 2vw;
      }
    }
    .steerWordingBox {
      padding: 2vw;
      text-align: center;
      .steerWording {
        width: 50%;
      }
    }
  }
  .steerImg {
    width: 100%;
  }
}
</style>

安卓用户,手动点击右上角打开其他浏览器。用户都是懒蛋,如果想让懒蛋们体验更好一点,也可以,用下边的方式,需要使用到blob链接,我在这里把后端传的base64转为 blob链接,使用方式:

export const savePicture = (base64, fileName = "下载文件(测试).pdf") => {
  var arr = (",");
  var bytes = atob(arr[1]);
  let ab = new ArrayBuffer();
  let ia = new Uint8Array(ab);
  for (let i = 0; i < ; i++) {
    ia[i] = (i);
  }
  var blob = new Blob([ab], { type: "application/octet-stream" });
  var url = (blob);
  const el = ("a");
   = "none";
  ("target", "_blank");
  fileName && ("download", fileName);
   = url;
  (el);
  ();
  (el);
};

下载方式:(此时点击按钮会主动弹出在浏览器打开弹窗,无需用户点击右上角,此方法必须要blob链接,此方法必须要blob链接,此方法必须要blob链接):

import { savePicture } from "@/utils/util";

download() {
if (appSource() !== "ios")
     savePicture("data:application/pdf;base64," + res.base64);
},

最优版本已经更新,下方点击进入

/qq_43586648/article/details/126894378?spm=1001.2014.3001.5501