本项目使用 mpvue 框架开发小程序,小程序或者h5项目可参考,大体都一样的逻辑。效果如下:
首先比较重要的一点,就是要请求后端接口获取 oss的签名,oss的签名是啥?可以参考 oss官方文档
https://help.aliyun.com/document_detail/92883.html?spm=a2c4g.11186623.6.650.61462f08xMkvoQ
也就是前端不应该把oss 的AccessKeyId和AccessKeySecret写在前台,而是应该让后端 把AccessKeyId,AccessKeySecret 生成一个签名,前端通过接口获取这个签名,然后凭借签名把图片上传到阿里云服务器。
获取AccessKeyId,AccessKeySecret
记得把阿里云外网访问地址配置在小程序后台白名单
代码如下:
<template>
<div class="authOwner">
<div class="imgContent cf">
<div class="imgDiv fl" v-for="(item,index) in tempFilePathsArr" :key="index" @click="previewImage($event,item)">
<img :src=item alt="">
<!-- <span class="iconImg"><i class="icon iconfont icon-shouye"></i></span> -->
<span class="deleteImg" @click.stop="deleteImg(index)"><i class="icon iconfont icon-shanchu"></i></span>
</div>
<div class="chooseImg fl" @click="chooseImg" v-if="tempFilePathsArr.length < 9">
<img class="caseImg" v-if="GLOB_DATA" :src="GLOB_DATA.CDN_PATH + '/static/image/authOwner/plus.png'">
</div>
</div>
<div class="uploadDiv">
<div class="uploadBtn" @click="toUpload">提交审核</div>
</div>
</div>
</template>
<script>
import uploadImage from '@/assets/js/uploadFile.js'// 图片上传组件
export default {
data () {
return {
tempFilePathsArr: [],
sign: {}
}
},
onLoad () {
// 获取 oss签名
this.getOssSign(5001, 'user')
// 初始 图片数组数据
this.tempFilePathsArr = []
// 以下可以作为 页面再次进来时 再次渲染上次 提交的图片
if (wx.getStorageSync('noAuthInfo')) {
this.tempFilePathsArr = wx.getStorageSync('noAuthInfo').contract_images
}
},
onUnload () {
// 页面卸载时 清空页面数据
Object.assign(this.$data, this.$options.data())
},
methods: {
getOssSign (module, apiName) { // 和后台交互 获取 oss的签名
let that = this
this.$http.post(`/api/miniprogram/oss/sign`, {module: module}).then((res) => {
if (res.code === 0) {
// 获取签名
that.sign = res.data
} else {
console.log(res.msg)
}
}).catch(err => {
console.log(err.status, err.message)
})
},
chooseImg: function () {
let that = this
wx.chooseImage({
count: 9 - that.tempFilePathsArr.length, // 默认最多一次选择9张图
sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: function (res) {
// 支持多图上传
for (var i = 0; i < res.tempFilePaths.length; i++) {
// 验证格式
if (!/.(jpg|jpeg|png)$/i.test(res.tempFilePaths[i])) {
console.log('第' + (i + 1) + '图片格式不对,格式必须是jpeg,jpg,png中的一种')
return
}
// 显示消息提示框
wx.showLoading({
title: '图片上传中...',
mask: true
})
// 参数: 上传的图片临时文件路径、签名、成功回调、失败回调
uploadImage(res.tempFilePaths[i], that.sign,
function (result) {
console.log('======上传成功图片地址为:', result)
// 做你具体的业务逻辑操作
that.tempFilePathsArr.push(result)
console.log(that.tempFilePathsArr)
wx.hideLoading()
}, function (result) {
console.log('======上传失败======', result)
// 做你具体的业务逻辑操作
wx.hideLoading()
}
)
}
}
})
},
deleteImg (index) {
let that = this
wx.showModal({
title: '提示',
content: '确定删除这张照片吗?',
confirmColor: '#c6ae6c',
success (res) {
if (res.confirm) {
that.tempFilePathsArr.splice(index, 1)
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
},
// 小程序图片预览
previewImage: function (e, item) {
console.log('item' + JSON.stringify(item))
wx.previewImage({
current: item, // 当前显示图片的http链接
urls: this.tempFilePathsArr // 需要预览的图片http链接列表
})
},
// 提交审核
toUpload () {
if (this.tempFilePathsArr.length === 0) {
wx.showToast({
title: '请上传图片',
icon: 'none',
duration: 2000
})
return false
}
// 接下来做自己的操作
// this.tempFilePathsArr 图片数组
}
}
}
</script>
<style lang="less" scoped>
.authOwner{
padding-top: 80rpx;
.imgContent{
width: 630rpx;
margin: 0 auto;
.imgDiv{
width:200rpx;
height:200rpx;
margin: 10rpx 10rpx 0 0;
position: relative;
img{
width: 100%;
height: 100%;
}
.deleteImg{
position: absolute;
right: -8rpx;
top: -20rpx;
width: 40rpx;
height: 40rpx;
background-color: #fff;
display: inline-block;
border-radius: 50rpx;
display: flex;
justify-content: center;
align-items: center;
.iconfont{
font-size: 32rpx;
color: #C6AE6C;
}
}
}
.chooseImg{
width:200rpx;
height:200rpx;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
background:rgba(245,245,245,1);
border-radius:2px;
margin: 10rpx 10rpx 0 0;
img{
width: 80rpx;
height: 80rpx;
}
}
}
.uploadDiv{
margin-top: 80rpx;
text-align: center;
.uploadBtn{
display: inline-block;
width:360rpx;
height:100rpx;
line-height: 100rpx;
background:rgba(198,174,108,1);
border-radius:2px;
font-size:28rpx;
font-weight:400;
color:rgba(255,255,255,1);
}
}
}
</style>
<img class="caseImg" v-if="GLOB_DATA" :src="GLOB_DATA.CDN_PATH + '/static/image/authOwner/plus.png'">这个图片文件(上传的那个+ 号)随便换成一个你自己本地的图片图标。
和后台交互获取 oss签名的接口返回如下
uploadFile.js文件
/*
*上传文件到阿里云oss
*@param - filePath :图片的本地资源路径集合
*@param - sign:后台返回的签名信息
*@param - successc:成功回调
*@param - failc:失败回调
*/
const uploadFile = function (filePath, sign, successc, failc) {
if (!filePath) {
wx.showModal({
title: '图片错误',
content: '请重试',
showCancel: false
})
return
}
// 图片名字 可以自行定义,这里是采用当前的 文件名 + 时间戳 + 150内的随机数来给图片命名的
const aliyunFileKey = sign.dir + new Date().getTime() + Math.floor(Math.random() * 150) + '.png'
const aliyunServerURL = sign.host + '/'// OSS地址,需要https
const accessid = sign.accessid
const policyBase64 = sign.policy
const signature = sign.signature// 获取签名
// let formData = {
// 'key': aliyunFileKey,
// 'policy': policyBase64,
// 'OSSAccessKeyId': accessid,
// 'signature': signature,
// 'success_action_status': '200'
// }
// console.log('formData----------' + JSON.stringify(formData))
wx.uploadFile({
url: aliyunServerURL, // 开发者服务器 url
filePath: filePath, // 要上传文件资源的路径
name: 'file', // 必须填file
formData: {
'key': aliyunFileKey,
'policy': policyBase64,
'OSSAccessKeyId': accessid,
'signature': signature,
'success_action_status': '200'
},
success: function (res) {
if (res.statusCode !== 200) {
failc(new Error('上传错误:' + JSON.stringify(res)))
return
}
successc(aliyunServerURL + aliyunFileKey)
},
fail: function (err) {
err.wxaddinfo = aliyunServerURL
failc(err)
}
})
}
export default uploadFile
好了,代码入上。
卓越的云计算服务提供商,230万+用户正在享受阿里云"稳定,安全,低成本"的产品服务,金牌服务:免费体验,专业快速备案,7x24小时售后,服务器只选阿里云