目录
一、已解决的问题
1、a标签无法下载/预览文件
2、企业微信自建应用调试工具不显示log信息
3、从B页面返回A页面,定时器不会自动清除,重新进入B页面,vuex也不会恢复初始数据
4、 iframe标签无法预览PDF
5、企微消息通知进入应用的某个详情页,无法返回上一页
二、未解决的问题
1、使用router.push进行页面跳转,点击左上角图标会退出应用
2、页面编辑状态校验,返回上一页无法拦截已编辑状态
一、已解决的问题
1、a标签无法下载/预览文件
(1)<a>标签、组件库的link标签。
问题:因文件做加密,所以无法成功请求。如果不考虑文件私密性的话,可以尝试使用(用uniapp+企业微信自建应用使用过,没出现问题)。
(2)从后台获取文件流进行转化。
问题:安卓能正常显示查看,但是ios不支持。
const data = res const url = window.URL.createObjectURL(new Blob([data])) const link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', file.name) document.body.appendChild(link) link.click()
复制
(3)企业微信自建应用开发SDK+api下载。
官网地址:
wx.config --使用说明 - 接口文档 - 企业微信开发者中心
wx.previewFile--文件接口 - 接口文档 - 企业微信开发者中心
实现过程如下:
1)ios大多识别不到jWeixin,需要转换一下。建议public/index.html中,全局修改jWeixin。(也可以哪里使用哪里修改)
<script> let soianWX; if (jWeixin.config) { soianWX = jWeixin; } else { soianWX = wx; } </script>
复制
2)同样在该文件,建议使用引入的方式,引入JS文件。
(两个版本都引入,免得部分api缺失,还要花精力去找为什么【***api is not a function】或【***api undifined】)
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <script src="https://res.wx.qq.com/wwopen/js/jsapi/jweixin-1.0.0.js "></script>
复制
3)请求企业微信sdk
大部分的api都不支持直接使用的,比如当前使用的.previewFile、拉取用户隐私、打开会话等等等等,都需要请求企业微信sdk。
因sdk注册一次规定时间内都能使用,且有开销限制,所以建议封装请求,然后在页面内单独请求api。
// 引入加密插件 import sha1 from 'js-sha1' /** * 拼接签名字符串 * @param ticket 通过access_token获取的jsapi_ticket * @param noncestr 自己生成的随机字符串 * @param timestamp 生成签名时的时间戳 */ export function getSignature(ticket, noncestr, timestamp) { const url = window.location.href const TICKET = 'jsapi_ticket=' + ticket + '&noncestr=' + noncestr + '×tamp=' + timestamp + '&url=' + url return sha1(TICKET) } // 获取js-sdk export async function JWeixinConfig(state, url, Obj) { // 生成签名 let ticket = '' // 生成时间戳 const timestamp = Date.parse(new Date()) // 生成的随机字符串 const nonceStr = randomString(16) // 获取企业微信配置项,肯定是后端生成更为安全 await getJWeixinTicket().then(res => { ticket = res.data }) // 必须步骤--获取sdk鉴权 soianWX.config({ // 必须这么写,否则wx.invoke调用形式的jsapi会有问题 beta: true, // 调试, true可以查看线上api信息,方便看报错 debug: false, // 企业微信应用id,必填 appId, // 时间戳,必填 timestamp, // 随机字符串,必填 nonceStr, // 签名字符串,必填 signature: getSignature(ticket, nonceStr, timestamp), // 需获取权限的api,必填 jsApiList: [ 'previewFile', 'invoke' ] }) // ready,必须步骤 soianWX.ready((res) => { // 下载附件 --这里可以通过state传入的字符串做判断,使用哪些api,防止页面内使用api时无法成功获取,在此处再次调用。 soianWX.invoke('previewFile', { url, // 需要预览文件的地址(必填,可以使用相对路径) name: Obj.name, // 需要预览文件的文件名,必须有带文件格式的后缀,例如.doc(不填的话取url的最后部分,最后部分是个包含格式后缀的文件名) size: Obj.size, // 需要预览文件的字节大小(必填,而且大小必须正确,否则会打开失败) success: (response) => { console.log('下载成功走这里', response) }, fail: (err) => { if (err.errMsg.indexOf('function not exist') > -1) { Toast.html('版本过低请升级') } }) } // error,必须步骤 soianWX.error((res) => { soianWX.cppsysStatus = false }) }
复制
4)页面内使用。
以上信息全配置好了,页面内绑定click事件就可以直接使用了。如果走fail且非版本问题,再重新获取sdk。
soianWX.previewFile({ url, // 需要预览文件的地址(必填,可以使用相对路径) name: file.name, // 需要预览文件的文件名,必须有带文件格式的后缀,例如.doc(不填的话取url的最后部分,最后部分是个包含格式后缀的文件名) size, // 需要预览文件的字节大小(必填,而且大小必须正确,否则会打开失败) success: (res) => { console.log('下载成功走这里', res) }, fail: (res) => { if (res.errMsg.indexOf('function not exist') > -1) { this.$toast('版本过低请升级') return } JWeixinConfig('previewFile', url, { name: file.name, size }) } })
复制
5)说明:
问题1:如果文件是采用文件流的方式返回,size的获取方式如下:
getFileDownload(file.path).then((res) => { // 从流的头部获取文件大小字段 const size = new Blob([res]).size })
复制
(当然后端能给处理就省事多了)。
问题2:为什么页面内请求.previewFile和封装使用的方式不太一样?
好问题,但我也说不明白,或许可以问问企业微信开发团队是怎么想的。
其实页面内那个写法,是官网示例写法,正常按照【config——ready——api——error】的顺序使用是没有问题的。
但是封装使用后,不论鉴权是否过期,页面里ios偶尔不支持jWeixin.previewFile下载;只要鉴权没过期,安卓就可以下载成功。此时在封装的地方,将'previewFile'和 'invoke'同时注册,并通过.invoke回调使用,ios和安卓就都支持。
其他api是否会出现这个问题不太清楚,没试过。
可以参考官方的这个说法。没实践过。
问题3:安卓打开txt文件会乱码,其它文件打开没有问题;ios显示正常。
应是QQ浏览器内核有点什么处理问题,因为安卓将文件下载后,使用其它浏览器、wps去查看和编辑,都是没有问题的。没有解决办法,网上说是文件格式的问题,还没来得及试试,感兴趣可以尝试。
实现思路:(1)先区分ios端还是android,ios使用wx.previewFile方法,android使用【(2)从后台获取文件流进行转化】的方式,在转化前判断文件为txt时强行更改文件格式url = window.URL.createObjectURL(new Blob([data], { type: 'text/plain,charset=UTF-8' })),再进行下载。
附分端处理代码
//是否为ios let isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent) // 区分移动端和pc端,如果是返回true,否则返回false export function isMobile() { let flag = navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i); return flag; },
复制
问题4:wx.config需要的信息也可以通过请求接口返回。
2、企业微信自建应用调试工具不显示log信息
因企业微信自建应用请求企业微信SDK本地无法调试,需要修改很多配置信息,所以需要借助线上调试工具查看控制台信息,辅助开发。
先检查config文件或main.js文件有没有对打包后的文件去log处理,如果没有,可以使用以下工具进行控制台打印查看。
1)移动端使用(有时可能会不出log信息和报错,只有网络请求信息)
<script src="https://cdn.bootcss.com/vConsole/3.3.4/vconsole.min.js"></script> <!-- ios测试环境调试 --> <script> new VConsole(); // 初始化 var vConsole = new VConsole(); </script>
复制
2)如果1)不好用,可以使用这个(亲测好用)
<script src="//cdn.bootcss.com/eruda/1.5.2/eruda.min.js"></script> <script> eruda.init(); </script>
复制
3)有些应用仅支持pc使用,不需要用app使用,那就可以直接使用官网提供的方法。
常见问题 - FAQ - 接口文档 - 企业微信开发者中心
3、从B页面返回A页面,定时器不会自动清除,重新进入B页面,vuex也不会恢复初始数据
原理我也不太清楚,不知道为什么pc不需要特意销毁和重置,但企业微信应用开发就不行。需要在destroyed(){}中销毁定时器,并恢复初始数据。
4、 iframe标签无法预览PDF
企业微信应用貌似是不支持的,用第三方包吧。
// npm下载 npm i pdfh5 // 页面引入 import Pdfh5 from 'pdfh5' import 'pdfh5/css/pdfh5.css' <div id="pdfType" /> // 接口请求对流转换拿到url if (res.size !== 0) { const blob = new Blob([res], { type: 'application/pdf' }) const url = URL.createObjectURL(blob) this.baseUrl = url } // pdf预览 initPdf() { this.pdfh5 = new Pdfh5('#pdfType', { pdfurl: this.baseUrl, // pdf文件地址(我用的文件流转换的url,可以使用) lazy: false, // 是否懒加载,默认false,文件流形式只显示2页,后边加载不出,建议关闭 renderType: 'canvas', // canvas、svg,默认canvas maxZoom: 3, // 手势缩放最大倍数,默认3 scrollEnable: true, // 是否允许pdf滚动,默认true zoomEnable: true, // 是否允许pdf手势缩放,默认true limit: 0 // 限制pdf加载最大页数,默认0不限制 }) // 监听完成事件 this.totalNum在lazy为true时显示不正确,false时显示正确 // this.pdfh5.on('complete', function(status, msg, time) { // console.log('状态:' + status + ',信息:' + msg + ',耗时:' + time + '毫秒, 总页数:' + this.totalNum) // }) }
复制
5、企微消息通知进入应用的某个详情页,无法返回上一页
具体表现为:手势返回、左上角系统图标返回、左上角ios系统图标关闭应用,均无法返回上一页/关闭
原因:检查代码后发现,通过企微消息通知进入应用后,进入的是空白页,空白页对不同的通知消息再跳转不同的处理页/详情页时,使用的是this.$router.push(),当我们返回上一页,其实返回的是空白页(而不是退出系统),空白页再次进行处理重新跳转回处理页/详情页,造成“退不出去”的错觉……
修改:this.$router.replace() 跳转,将当前空白页关闭。
二、未解决的问题
1、使用router.push进行页面跳转,点击左上角图标会退出应用
ios:手势返回、左上角返回上一页正常。
安卓:手势返回无问题,左上角返回会退出应用。
原理还不清楚。
2、页面编辑状态校验,返回上一页无法拦截已编辑状态
安卓:因点击返回直接退出应用,无法校验能否拦截。手势返回没有试过,参考微信小程序框架开发经验来看,企业微信自建应用应该是有自己的api可以做拦截的。
ios:官网文档明确说明,怎样都不行。只能有提示信息,拦是拦不住的。