背景:需要在 微信公众号 内实现,通过点击一个【下载PDF文件】按钮,预期将 PDF 文件下载到本地自行打印。
前言:首先,本文采用的是 配合 后端 的实现方案。后端 返回file文件,通过 a 链接实现下载。
后端接口为【get】请求,返回 file 文件,所以可以直接访问。
问题:
- ios 系统 在微信浏览器里,通过【window.location.href = '后端下载链接' 】的方式,下载的文件打不开,因为微信浏览器不支持。需要 引导用户到外部浏览器下载,可通过一个中间页,放一个 下载 按钮。
- 需指定下载文件名后缀为【 .pdf】,不然下载下来的是文本。
- 在 进行axios请求时,需要添加 responseType为 ‘arraybuffer’,不然下载下来是空白的。
正文:
- 下载页面的写法
methods: {
downLoadPdf () {
let u = navigator.userAgent
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
if (isIOS) {
this.$router.push({
path: '/downLoadForIos', // IOS下载中间页
query: {}
})
} else {
const pdfUrl = '后端提供的get请求接口完整路径'
// pdfUrl格式类似:http://csdn.net/agreement/downloadpdf?query1='user'
window.location.href = pdfUrl
}
}
}
- ios 下载中间页
- 引导用户外部浏览器打开
- axios 请求时需指定 responseType 为 arraybuffer
<template>
<div class="download_ios">
<div class="mask" v-if="isWeiXin">
<div class="tips">1、点击右上角图标</div>
<div class="tips">2、选择 在浏览器中 打开</div>
</div>
<div class="button" v-else>
<button @click="downloadAgreementPdf>下载PDF</button>
</div>
</div>
</template>
// 导入 axios
export default {
data () {
isWeiXin: true
},
created () {
this.getIsWxClient()
},
methods: {
getIsWxClient () {
const ua = navigator.userAgent.toLowerCase()
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
this.isWeiXin = true
} else {
this.isWeiXin = false
}
},
downloadAgreementPdf () {
const fileName = '协议'
let data = '后端返回的文件数据' // 注意:请求时需指定 responseType 为 arraybuffer
// let data = this.getData('接口url', '附带参数')
if (data) {
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement(('a'))
link.style.display = 'none'
link.href = url
link.setAttribute('download', `${fileName}.pdf`)
document.body.appendChild(link)
link.click()
URL.revokeObjectURL(link.href)
document.body.removeChild(link)
}
},
// 请求后端数据
getData (url, params) {
return axios({
baseURL: '替换成自己的域名',
url: '替换成接口的url',
method: 'get',
params: params,
headers: {
'Content-Type': 'application/json'
},
responseType: 'arraybuffer'
})
}
}
}
<style>
.mask {
width: 100%;
height: 100vh;
background-color: #666666;
padding-top: 30%;
}
.mask .tips {
color: #ffffff;
text-align: center;
margin-bottom: 20px;
}
.button {
width: 90%;
padding: 5%;
}
</style>