因为我们之前使用的上传图片在上传比较大的图片时回显耗时很长,所以要求改用七牛云,根据领导给的参考和自己查的资料,做出来一个比较简单的可以满足需求。
首先需要进行准备工作:
内容参考这里(领导给的参考,因为部分准备工作已经做过了,所以我这里就直接从我自己做过的开始)↓
https://zhuanlan.zhihu.com/p/159399992
1.实名认证后,和后端配合,给你一个接口去调用获取到七牛token (这个token可以存储在app.globalData里,方便后面使用)
在这里你要选择自己的上传的地区,一共有五个,详情请自己在github上面去看,还是比较详细的,另外有一个domain的配置,是回显的时候用的,是自己公司的配置好的(开始我以为是配置我选择的那个区域的地址,后来找了很久,然后试了公司的链接后发现的,如果你在参考这篇笔记,还是需要自己试一下的)
2.接口可以调通后,去github上下载sdk文件包
软件开发工具包 - 七牛开发者中心这是参考里面给的链接,但是你可以直接从github上拉
gitHub链接:https://github.com/gpake/qiniu-wxapp-sdk
git clone https://github.com/gpake/qiniu-wxapp-sdk.git
3.打开sdk包,把qiniuUploader.js导入你需要的小程序中,我放在了utils文件夹里,
4.剩下的就好说啦,这里封装了公共方法,借鉴的是:记录小程序使用七牛云上传图片详细步骤及遇到的坑 小程序七牛云上传文件代码封装_七牛云 小程序-CSDN博客
目前这个场景是:点击按钮调用wx.chooseMedia,仅支持单张,没有做任何处理(大小压缩等):
//upload.js const { getToken } = require("../api/getQiniuToken.js") // 获取七牛云token接口 const qiniuUploader = require("./qiniuUploader.js"); // 引入七牛云js const app = getApp(); // 获取应用实例 /** * 初始化七牛相关参数 * @param {*} res 拿到的七牛云token * @param {*} region 上传区域 ECN, SCN, NCN, NA, ASG,分别对应七牛的:华东,华南,华北,北美,新加坡 5 个区域 * @param {*} uptoken 七牛云token * @param {*} domain bucket 域名,下载资源时用到。如果设置,会在 success callback 的 res 参数加上可以直接使用的 ImageURL 字段。否则需要自己拼接。 * @param {*} shouldUseQiniuFileName qiniuShouldUseQiniuFileName 如果是 true,则文件的 key 由 qiniu 服务器分配(全局去重)。如果是 false,则文件的 key 使用微信自动生成的 filename。出于初代sdk用户升级后兼容问题的考虑,默认是 false。 * 微信自动生成的 filename较长,导致fileURL较长。推荐使用{qiniuShouldUseQiniuFileName: true} + "通过fileURL下载文件时,自定义下载名" 的组合方式。 * 自定义上传key 需要两个条件:1. 此处shouldUseQiniuFileName值为false。 2. 通过修改qiniuUploader.upload方法传入的options参数,可以进行自定义key */ const initQiniu = (res) => { var options = { region: 'ECN', // 华东 uptoken: res, // uptokenURL: 'https://[yourserver.com]/api/uptoken', // uptoken: '', domain: '此处为自己公司配置的网址', shouldUseQiniuFileName: false }; qiniuUploader.init(options); } /** * 获取token, getToken是自己封装的接口请求方法,然后使用promise异步返回结果 */ const getUploadToken = () => { return new Promise((resolve,reject)=>{ getToken().then(res =>{ if(res.data.message) { app.globalData.uploadParams = res.data.message;//此处放在app globalData里是为了避免重复获取token,本次使用期间可以无需重复获取 initQiniu(res.data.message) //如果在uploadImg中配置,则不需要init resolve(res.data.message) } }) }) } /** * 上传七牛 * @param {*} params 主要存储了上传到七牛云的区域及上面接口获取到的upToken值 * @param {*} files 图片文件 */ const uploadImg = (params,files) => { var state = 0; // 上传第几张图片 var imgList = []; // 保存图片数组 // let fileList = files.map(item => item.url); //若files是有url键的对象,则可map进去,但目前只考虑wx自带单张选择图片的情况 let fileList = []; fileList.push(files) var uploadArr = fileList; // chooseMedia上传成功的数组 var uploadNum = fileList.length; // 上传数组的长度 return new Promise((resolve, reject)=> { for (let i = 0; i < uploadNum; i++) { var random = Math.floor(Math.random() * 10000); //随机数 qiniuUploader.upload(uploadArr[i], (res) => { // 以下注释内容是针对多张上传的图片做出处理,返回的是图片地址的数组 // state++; // imgList.push(res.imageURL); // if (state == uploadNum) { // resolve(imgList); // } resolve(res) }, (error) => { reject('error'); console.log('error: ' + error); wx.hideLoading(); }, // 以下为option中的自行配置参数,由于在init时就已经配置,所以这里注释掉,但可选择不init,在这里配置参数, // { // uploadURL: params.uploadURL, //上传到七牛的那个存储区域所对应的前缀地址,详见SDK中的区域图(如:"https://up.qiniup.com")。 // domain: 'qiniu.pudu.live',//CDN加速域名,无需修改 || 按照自己需求,配置的下载地址 // uptoken: params.uploadToken, //服务端接口获取的七牛token值,我们这边后台返回的字段名为uploadToken,需要换成你们的自定义字段哦 // region: 'ECN',//上传区域,共有五个,按需选择 // key: null, // 图片自定义名称 避免名称重复此处设置为null可以解决上传undefined file exists问题 // } ) } }) } module.exports = { getUploadToken, uploadImg }
//所需组件 .wxml <text bindtap="getQiNiuToken">选择图片</text> <image src="{{imageObject.fileURL}}" mode="aspectFit"></image> // 所需组件的 .js import { uploadImg,getUploadToken } from "../../utils/upload" data:{ imageObject: {}, // 图片上传(从相册)返回对象。上传完成后,此属性被赋值 } //上传图片 handleUpload(params,file,type){ uploadImg(params,file).then((imgObj)=>{ console.debug("上传成功 files",imgObj); this.setData({ imageObject: imgObj }) }).catch((error)=>{ console.log("图片上传失败",error); }) }, //选择图片 检查是否有七牛token getQiNiuToken() { let _this = this; // 置空messageFileObject,否则在第二次上传过程中,wxml界面会存留上次上传的信息 _this.setData({ imageObject: {}, imageProgress: {} }); wx.chooseMedia({ count: 1, // 目前仅支持单张上传 mediaType: ['image','video'], sourceType: ['album', 'camera'], maxDuration: 30, camera: 'back', success(res) { let filePath = res.tempFiles[0].tempFilePath; //图片地址 let uploadParams = app.globalData.uploadParams; //判断是否已经请求过上传token if(uploadParams) { _this.handleUpload(uploadParams,filePath) } else { getUploadToken().then((res)=>{ //globalData没有上传所需参数,先获取token再上传图片 _this.handleUpload(res,filePath); }) } } }) },
这样就可以实现一个最简单的上传、回显,中间遇到很多不懂的也是边查边试出来的,很多逻辑都不懂,但是功能实现了,各位大佬有更好的可以留言指正。