小程序选择图片、预览,上传到阿里云
2020-05-15 本文已影响0人
苏北苝
小程序开发过程中需要用户发布内容,图片、文字、视频,在小程序里发布有自己的api,感觉比html要方便的多。
需求:一个发布页面,选择图片按钮,和选择视频按钮,点击图片可以选择多张图,图片和视频不能同时存在,这边我们是文件直接上传到阿里云的,剩余在和后端交互。话不多说,进入正题。
老样子,先上文档,
一、选择图片并预览 点击查看微信文档
选择成功回调image.png
1、参数就不过多解读了,大家都看得懂,因为选择9张图,所以在回调里做判断图片个数,上个demo
//选择图片
chooseImg() {
let that = this,
worksImgs = this.data.worksImgs; //存储本地图片的数组
wx.chooseImage({
count: 9 - worksImgs.length, //剩余可选几张照片
sizeType: ['original', 'compressed'], //可选择原图或压缩后的图片
sourceType: ['album', 'camera'], //可选择性开放访问相册、相机
success(res) {
// tempFilePath可以作为img标签的src属性显示图片
const images = worksImgs.concat(res.tempFilePaths) //把选择的照片放入worksImgs
that.setData({
worksImgs: images
})
},
error(res) {
// 这里的operate.hintToast() 是我自己封装的一个错误提示方法
operate.hintToast(res.errMsg);
}
})
}
2、正常选择图片都可以进行删除,就是删除上面存储图片的数组中对应的元素,so:
wxml:
<block wx:for="{{worksImgs}}" wx:key="key">
<view class="box">
<image src="{{item}}" mode="aspectFill"></image>
<view class="weui-icon" data-index="{{index}}" bindtap="deleteImg"></view>
</view>
</block>
JS:
// 删除图片 对应每个图片右上角的x号
deleteImg(e) {
let worksImgs = this.data.worksImgs;
let itemIndex = e.currentTarget.dataset.index;
worksImgs.splice(itemIndex, 1);
this.setData({
worksImgs: worksImgs
})
},
3、在选择图片之前判断是否有视频资源,图片和视频不能同时存在,
if (this.data.videoSrc) {
operate.hintToast('无法同时选择发布视频和图片!');
return false;
};
4、上传到阿里云:
如果请求出现oss跨域请求,可能是你的阿里云地址没有设置跨域规则,参考 跨域CORS规则设置,官方介绍的很清楚,按着配置就行。
- 上传需要用到wx.uploadFile,如图: uploadFile
上传到阿里云,需要注意你的阿里云是RAM还是STS,我们STS临时授权的,所以需要动态获取阿里云账号口令放在app.globalData里;看了几个固定的(RAM格式)是直接放在文件里的;
- 在需要上传文件的page页面,进行口令验证,如果过期了就重新请求新的口令;
上传的相关文件我放在GitHub
里,upload文件夹下是上传阿里云相关文件,其中uploadFile.js 上传主要文件,其他是相关算法 ,不做详细解释,具体说一下其中需要注意的几个点;(下载可以直接使用,但是要改成你自己的地址)
(1)动态STS需要设置x-oss-security-token,不可少!
//请求到你的阿里云密令进行赋值
const formData = {
key: aliyunFileKey,
policy: policyBase64,
OSSAccessKeyId: accessid,
signature: signature,
success_action_status: '200',
'x-oss-security-token':env.stsToken
};
(2)上传文件时需要设置上传文件的限制大小,图片一般不会超,视频超出如果没有限制,会报错的!!!(一定要注意)
在getPolicyBase64 这个方法里进行设置(封装在uploadFile.js )
const getPolicyBase64 = function (num) {
// 视频 250M 图片 20M
let date = new Date();
date.setHours(date.getHours() + env.timeout);
let srcT = date.toISOString();
const policyText = {
"expiration": srcT, //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了
"conditions": [
["content-length-range", 0, num * 1024 * 1024] // 设置上传文件的大小限制
]
};
const policyBase64 = base64.encode(JSON.stringify(policyText));
return policyBase64;
};
- 接着上传,因为是多图上传,常规我们想到的就是for循环,但是for循环不能保证每次循环都是在上一张图片成功之后在进行下一次,所以可能产生图片顺序错乱;由此,我们在每次成功之后在执行下一次上传,保证图片是按照正确的顺序。
- 因为在过程中用户会对图片进行删除,替换等,我们把上传图片放在最后点击发布按钮的时候,先上传文件到阿里云,拿到回调地址,再传给后端进行发布。
下面这一段是上传核心代码
uploadImg: function (i) {
let that = this, worksImgs = that.data.worksImgs;
let nowTime = util.formatTime(new Date());
console.log(i,worksImgs);
wx.showLoading({
title: '发布中...',
mask: true
});
if (i >= worksImgs.length){
that.publish();
}else if (worksImgs[i].indexOf('oss-cn-hangzhou.aliyuncs.com') > -1 ){
//判断当前图片是不是已经上传过的
i++;
if (i >= worksImgs.length) {
that.publish();//最后一张上传完成,进行其他操作发布
} else {
that.uploadImg(i)
};
}else{
// 这里是uploadImage 方法传的几个参数(图片的本地资源路径,要传到哪个目录下)
upload.uploadImage(worksImgs[i], 'sds/xcx/your/'+ '-' + nowTime,
function (result) {
console.log("======上传成功图片地址为:", result);
let temp = 'worksImgs['+i+']';
that.setData({
[temp]: result
});
console.log(that.data.worksImgs)
}, function (result) {
console.log("第" + (i + 1) + "张上传失败" , result)
operate.hintToast("第" + (i + 1) + "张上传失败:"+result)
},function(com){
i++;
if (i >= worksImgs.length) {
that.publish(); //最后一张上传完成,进行其他操作发布
} else {
that.uploadImg(i)
};
}
)
}
},
效果见下图:
1.gif