微信小程序使用webview实现文件上传功能(uni-app)
项目开发了一个批示单的功能,用户填写批示单信息要上传正文及附件(多文件上传,有需要可在文章末尾查看),上传文件功能原调用的是uni.chooseMessageFile方法选择聊天记录中文件。
问题:用户在电脑端打开小程序后发现选择文件按钮点击无反应。
百度后发现此方法电脑端无法使用,并且微信平台暂时没有具体方法,有网上小伙伴说用webview结合input实现。
具体实现:
原设计:A页面选择添加文件后提交
修改后:添加一个B页面(upload文件),在B页面引入webview
A页面跳转到 ===> B页面 接入webview ===> webview(html)使用input选择文件 文件获取后postMessage并返回,具体代码如下
B页面(uploadFile.vue)
<template>
<view>
<!-- 测试完成后改为线上地址 -->
<web-view src="http://127.0.0.1:5500/%E4%B8%8A%E4%BC%A0%E6%96%87%E4%BB%B6/uploadFile.html"
@message="handleMessage"></web-view>
</view>
</template>
<script>
export default {
methods: {
handleMessage(e) {
console.log('接收到的消息:' + JSON.parse(e.detail.data));
uni.setStorageSync('fileMsg', JSON.parse(e.detail.data))
}
}
}
</script>
uploadFile.html
创建一个文件夹用来存放webview资源(uploadFile.html是在小程序中接入,本地测试时用vscode打开文件,使用live Serve创建一个本地服务,将服务地址复制放在B页面webview的src中)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>上传文件</title>
<style>
.uploadFilePage {
display: flex;
flex-direction: column;
align-items: center;
}
.inputBox {
width: 320px;
height: 220px;
color: #228EFF;
font-size: 18px;
margin-top: 100px;
border: 1px dashed #228EFF;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.inputBox img {
width: 130px;
height: 130px;
margin-bottom: 15px;
}
.inputBox .tips {
font-size: 12px;
color: #666;
line-height: 30px;
}
.fileInput {
display: none;
}
.fileList {
line-height: 35px;
margin-top: 20px;
}
.fileList .fileOne {
display: flex;
align-items: center;
}
.fileList .deleteIconBox {
width: 50px;
height: 35px;
display: flex;
align-items: center;
justify-content: center;
}
.fileList .deleteIconBox img {
width: 26px;
height: 26px;
}
.goBackBtn {
width: 120px;
height: 45px;
line-height: 45px;
text-align: center;
background-color: #228EFF;
border-radius: 6px;
color: #fff;
margin-top: 35px;
}
.alert {
position: fixed;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
padding: 10px;
background-color: #faa734;
color: #fff;
border-radius: 6px;
}
</style>
<!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->
<script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<!-- uni 的 SDK,必须引用。 -->
<script type="text/javascript" src="//js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js"></script>
<script src="./vue.min.js"></script>
</head>
<body>
<div class="uploadFilePage" id="app">
<div class="inputBox" @click="makeFileInputClick">
<img src="./image/uploadIcon.png" alt="">
<div class="text">点击上传</div>
<div class="tips">* 文件大小限制为10MB</div>
<input type="file" class="fileInput" name="222" @change="chooseFile" ref="fileInput">
</div>
<div class="fileList">
<div v-for="(item, index) in filesList.basicData" :key="index" class="fileOne">{{item.name}} 上传成功 <div
class="deleteIconBox" @click="deleteFile(index)"><img src="./image/deleteIcon.png" alt="">
</div>
</div>
</div>
<div @click="goBack" class="goBackBtn">完成</div>
<div class="alert" v-show="isShowAlert">文件大小超过限制,请重新上传</div>
</div>
<script>
console.log(Vue);
new Vue({
el: '#app',
data: {
filesList: {
basicData: [], // 原始数据
handledData: [] // 转化为base64的数据
},
isShowAlert: false
},
methods: {
makeFileInputClick() {
this.$refs.fileInput.click()
},
// 文件转base64
fileToBase64(file) {
return new Promise(function (resolve, reject) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
typeof reader.result === 'string' && resolve(reader.result) || reject();
};
reader.onerror = function (error) { return reject(error); };
});
},
async chooseFile(e) {
let fileList = this.$refs.fileInput.files
for (const item of fileList) {
// 限制文件大小
if (item.size / 1024 / 1024 > 10) {
this.isShowAlert = true;
setTimeout(() => {
this.isShowAlert = false;
}, 2500)
return
}
this.filesList.basicData.push(item);
this.filesList.handledData.push({ name: item.name, file: await this.fileToBase64(item) });
}
},
deleteFile(index) {
this.filesList.basicData.splice(index, 1)
this.filesList.handledData.splice(index, 1)
},
goBack() {
uni.postMessage({
data: JSON.stringify(this.filesList.handledData)
});
uni.navigateBack()
}
}
})
</script>
</body>
</html>
A页面
onShow() {
if (!uni.getStorageSync('fileMsg')) return
let fileMsg = uni.getStorageSync('fileMsg');
uni.removeStorageSync('fileMsg');
fileMsg.forEach(item => {
item.file = item.file.split('base64,')[1] // 不加此句是报了下图的错误,百度后是由于base64,及之前的原因,删除之后就不报错了
this.base64ToTempFilePath(item.name, item.file, (tempFilePath) => {
console.log('转换成功,临时地址为:', tempFilePath)
// 自己的业务逻辑...
}, function() {
uni.showToast({
title: '文件转换失败,请重试',
icon: 'none'
})
})
})
},
methods:{
base64ToTempFilePath(fileName, base64Data, success, fail) {
const fs = uni.getFileSystemManager()
// const fileName = 'temp_image_' + Date.now() + '.png' // 自定义文件名,可根据需要修改
const filePath = uni.env.USER_DATA_PATH + '/' + fileName
const buffer = uni.base64ToArrayBuffer(base64Data)
fs.writeFile({
filePath,
data: buffer,
encoding: 'binary',
success() {
success && success(filePath)
},
fail() {
fail && fail()
}
})
},
}
转换为base64时报错,删除base64 中开头的 data:xxx/xxx;base64, 即可
测试完成后,将html页面及相关文件上传至服务器,并在微信开放平台中进行配置 开发==>开发管理==>业务域名
多文件上传
微信小程序实现多文件同时上传文章来源:https://www.toymoban.com/news/detail-839764.html
本文基于以下文章所写:文章来源地址https://www.toymoban.com/news/detail-839764.html
- 使用webview实现小程序本地文件上传
- uni-app 将base64图片转换成临时地址
到了这里,关于微信小程序使用webview实现文件上传功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!