mpvue小程序、小程序图片上传到阿里云oss

本项目使用 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小时售后,服务器只选阿里云

猜你喜欢

转载自blog.csdn.net/qq_35430000/article/details/84983441