前往闪闪の小窝以获得更好的阅读和评论体验
背景
这个标题就已经够抽象了吧
本来用微信小程序的web-view去嵌套h5已经因为微信的种种限制(微信不希望你把微信小程序当做一个浏览器来用,它就是不想担责)导致微信登录、文件下载等种种微信特色问题已经很烦了,结果我们这有个场景是用uniapp开发出h5的页面,然后再用微信小程序的web-view去嵌套这个uniapp生成的h5页面……
本次下载场景的情况也是在文件下载的时候,安卓手机点击没反应,ios能打开文件但是都是乱码
解决方案
出现的问题跟这位老哥一模一样:
uniapp微信小程序使用webview嵌套h5的文件下载问题
他的解决方案是没错的但是遗漏了一些要点,这里结合在微信小程序官方文档以及另外一位知乎老哥较为完整的描述进行总结
一、思路
通过判断当前的设备环境来进行不同的操作,如果判断是微信小程序则在h5中跳转到小程序的特定页面,并且将文件资源的URL传递过去。之后在小程序中调用微信的下载文件或者保存文件API
二、引入依赖
这一步很关键,但是CSDN的老哥遗漏没讲
如果是普通h5,那么引入js:
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
如果是uniapp(本质上是Vue)或者Vue项目,需要安装依赖并引入:
npm install weixin-webview-jssdk
import wx from "weixin-webview-jssdk";
三、H5端代码
// 判断所在环境
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/micromessenger/i) == 'micromessenger') {
// console.log('是微信客户端')
uni.showModal({
title: '提示',
content: '是微信客户端:' + ua,
success: function (res) {
if (res.confirm) {
// 执行确认后的操作
// 打开微信特定页面,然后下载文件
var fileDownPath = 'https://www.baidu.com/img/flexible/logo/pc/result.png';
wx.miniProgram.navigateTo({
url: `/pages/file-upload/file-upload?url=${encodeURIComponent(fileDownPath)}`
})
}else {
// 执行取消后的操作
}
}
})
} else {
// h5端直接使用a标签下载
// this.downloadH5(fileDownPath,item.fieldName)
// console.log('不是微信客户端')
uni.showModal({
title: '提示',
content: '不是微信客户端:' + ua,
success: function (res) {
if (res.confirm) {
// 执行确认后的操作
}else {
// 执行取消后的操作
}
}
})
// 但我是uniapp
uni.downloadFile({
url: this.baseURL + url,
success: (res) => {
var filePath = res.tempFilePath;
uni.openDocument({
filePath: encodeURI(filePath),
showMenu: true,
fileType: fileType,
success: (res) => {
console.log('打开文档成功');
},
fail(err) {
console.log('小程序', err);
}
});
}
});
}
四、微信小程序端代码
- tip:每个页面只能有一个 web-view,web-view 会自动铺满整个页面,并覆盖其他组件。
- tip:web-view 网页与小程序之间不支持除 JSSDK 提供的接口之外的通信。
- tip:在 iOS 中,若存在 JSSDK 接口调用无响应的情况,可在 web-view 的 src 后面加个#wechat_redirect解决。
- tip:避免在链接中带有中文字符,在 iOS 中会有打开白屏的问题,建议加一下 encodeURIComponent
新建一个下载用的页面
获取参数URL调用微信小程序api去下载就行
// pages/file-upload/file-upload.js
Page({
/**
* 页面的初始数据
*/
data: {
url: ''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let that = this
let url = decodeURIComponent(options.url) // 解码
console.log(url);
this.setData({
url: url
})
wx.showLoading({
title: '加载中...',
})
wx.downloadFile({ // 下载文件
url: that.data.url,
success: function (res) {
that.setData({
tempFilePath:res.tempFilePath
})
let filePath = res.tempFilePath // 文件临时路径
console.log(filePath)
// debugger
that.downFile()
// wx.openDocument({ // 预览文件
// filePath: filePath,
// showMenu: true,
// success: function (res) {
// wx.hideLoading();
// },
// fail: function (error) {
// console.log(error);
// }
// })
},
fail: function (error) {
console.log(error);
wx.showToast({
title: '文件下载失败',
icon: 'error'
})
wx.hideLoading()
}
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
},
// 保存文件
downFile() {
wx.showLoading({
title: '文件保存中',
})
let that = this
wx.saveFile({ // 保存
tempFilePath: that.data.tempFilePath, // uploadFile返回的临时路径
success: (res) => {
let filePath = res.savedFilePath // 存放的路径
wx.showToast({
title: '保存成功:' + filePath,
icon: 'none'
})
setTimeout(() => {
wx.hideLoading({
success: (res) => {
wx.navigateBack({
delta: 1,
})
},
})
}, 1500);
},
fail: (err) => {
debugger
wx.showToast({
title: '文件保存失败',
icon: 'error'
})
console.log(err)
}
})
}
})