使用微信小程序选择图片,上传至腾讯云COS

背景

接到一个活儿:手机端小程序上传图片,压缩,传到腾讯云COS端,并展示到页面。
整合了:chooseImage,cos.postObject,故今天整理一下,供参考:

名词

1:以下代码如无特殊说明,即指微信小程序代码。
2:腾讯云对象存储COS:以下简称cos;
3:文中“小程序“,仅指微信小程序。

参考

1:小程序sdk说明文档:(选择图片)https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
2:微信COS,关于小程序的api:
https://cloud.tencent.com/document/product/436/31953

效果图展示

只是用于技术调用,页面丑,太丑,别介意。去掉了各种样式,页面代码量少(所有代功能都在同一页面完成),提高可读性,在交接时,接收人相对比较容易接受。
Alt
图1:初始界面,只有一个选择图片文件的按钮,按钮点击之后,进入微信预置的本地图片库的界面,这里使用了小程序的js方法:wx.chooseImage
图2:选中一个图片后,返回页面,且展示该图片,注意:这里的地址是:小程序的指定地址,非系统文件地址,后续上传到cos
图3:点击上传图片按钮,将小程序里的图片上传到cos,这里使用了cos针对小程序的api:cos.postObject。(注意与cos 针对网页js的方法不同)

开发步骤

1:概要步骤

1:使用了cos 小程序sdk,所以需要事先开通cos,配置好访问账号:SecretId,SecretKey,且在页面里引用 cos sdk。
后台需要事先开发好:后去cos授权的代码。用于构建cos对象getAuthorization方法里调用。
(cos-wx-sdk-v5.js)
2:使用小程序api:wx.chooseImage方法,打开微信图库。
3:使用cos的小程序api:cos.postObject。

2:上代码

1:引入相关js(小程序:index.js)

//index.js
//引入js
var COS = require('../../utils/cos-wx-sdk-v5.js')<!-- 引入cos sdk -->

2:小程序页面布局wxml(样式文件wxss省略)

<!--index.wxml-->
<view style="text-align:center;margin-top:20px;"  class="page_title">上传图片到腾讯COS测试</view>
<view class="container">
  <view class="usermotto_1">
   <button type="primary" bindtap="uploadImgFile">选择本地图片</button>
  </view>
  <view class="usermotto">
    <view  class="user-motto">{{motto}}</view><!--显示图片本地及上传cos之后的路径-->
  </view>
  <view class="usermotto_2">
    <image src="{{imgFileLocalPath}}" mode="widthFix"></image>
  </view>

  <view class="{{usermotto_uploadcos_class}}">
    <button type="warn" bindtap="uploadImgFile2TC">上传图片至腾讯云</button>
  </view>

</view>

3:index.js 主要方法:

  uploadImgFile: function() {//打开图库,选择图片
    this.setData({ motto: "选择图片" }),
    wx.chooseImage({
      count: 1,//限制一张图片
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success :res => {
        // tempFilePath可以作为img标签的src属性显示图片
        const tempFilePaths = res.tempFilePaths;//注意是数组
        console.log(tempFilePaths[0]);
        this.setData({imgFileLocalPath:tempFilePaths[0]});//取第一个元素
        this.setData({ motto: "已选择本地图片:"+this.data.imgFileLocalPath });
        this.setData({usermotto_uploadcos_class:'usermotto_uploadcos_show'});
        this.setData({needUploadFilePath:tempFilePaths[0]});
        this.setData({needUploadFileName:this.data.needUploadFilePath.substr(this.data.needUploadFilePath.lastIndexOf('/') + 1)});//提取文件名 
      }
    })
  }//方法结束

```javascript
//上传图片到cos
  uploadImgFile2TC:function(){
    var _this = this;
    var cos=getCosObj();//构建cos 对象,下面有单独定义
    console.log(cos);
    var filename=this.data.needUploadFileName;
    var filePath=this.data.needUploadFilePath;
    //上传文件
    cos.postObject({
        Bucket: app.globalData.COS_Bucket,
        Region: app.globalData.COS_Region,
        Key: 'wxapp_uploadfile/' + filename,
        FilePath: filePath,
        onProgress: function (info) {
            console.log(JSON.stringify(info));      
        }
    }, function (err, data) {
        console.log(err || data);
        if(data!=null){
          var fileCosFilePath=data.Location;//上传成功之后,返回路径信息,用于后台存库
          console.log("file cos path:="+fileCosFilePath);
          _this.setData({ motto: "腾讯云地址:" +fileCosFilePath});
          _this.setData({imgFileLocalPath:fileCosFilePath});
          _this.setData({usermotto_uploadcos_class:'usermotto_uploadcos_hide'});
        }      
    });
  }
  //返回COS地址
  //https://xxxxxx.cos.ap-shanghai.myqcloud.com/wxapp_uploadfile/xxxxxxxxxx6zAJs3kLbxxx3c7e2c63aBJxLNspL9tFU2YxvipU9d377b10ce778c4938229a.jpg

4:构建cos对象js方法,用于小程序端上传到cos,此方法最好定义到公共位置,以便于公用访问。
关于这部分后台代码,cos授权,参考:
https://cloud.tencent.com/document/product/436/14048

//通过后台,获取COS对象
/**
 * 返回一个cos对象
 */
function getCosObj(){
  console.log('getCosObj');
  return new COS({
    // ForcePathStyle: true, // 如果使用了很多存储桶,可以通过打开后缀式,减少配置白名单域名数量,请求时会用地域域名
    getAuthorization: function (options, callback) {
        // 异步获取临时密钥
        wx.request({
            url:  app.globalData.authcenterUrl+'/xxxxx?action=GET_STS_AUTH_ACTION',
            data: {
                bucket: options.Bucket,//固定写法
                region: options.Region,//固定写法
            },
            dataType: 'json',
            success: function (result) {
                console.log(result.data);
                var data = JSON.parse(result.data.AUTH_DATA);
                var credentials = data && data.credentials;
                console.log(data.credentials);
                if (!data || !credentials) return console.error('credentials invalid');
                callback({
                    TmpSecretId: credentials.tmpSecretId,
                    TmpSecretKey: credentials.tmpSecretKey,
                    XCosSecurityToken: credentials.sessionToken,
                    // 建议返回服务器时间作为签名的开始时间,避免用户浏览器本地时间偏差过大导致签名错误
                    StartTime: data.startTime, // 时间戳,单位秒,如:1580000000
                    ExpiredTime: data.expiredTime, // 时间戳,单位秒,如:1580000900
                });
            }
        });
    }
});
}

5:获取cos授权后台代码:GET_STS_AUTH_ACTION.java
主要代码:

//系统常量,启动时,从配置文件读取
//CommonContant.TX_COS_SecretId
//CommonContant.TX_COS_SecretKey
//CommonContant.TX_COS_bucket
//CommonContant.TX_COS_region
	protected int performExecute(ActionContext atx) {
		// TODO Auto-generated method stub
        TreeMap<String, Object> config = new TreeMap<String, Object>();

        try {
            // 替换为您的 SecretId -- 腾讯云 api 秘钥
            config.put("SecretId", CommonContant.TX_COS_SecretId);
            // 替换为您的 SecretKey
            config.put("SecretKey", CommonContant.TX_COS_SecretKey);
            // 临时密钥有效时长,单位是秒,默认1800秒,最长可设定有效期为7200秒
            config.put("durationSeconds", 1800);
            // 换成您的 bucket
            config.put("bucket", CommonContant.TX_COS_bucket);
            // 换成 bucket 所在地区
            config.put("region", CommonContant.TX_COS_region);

            // 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子:a.jpg 或者 a/* 或者 * 。
            // 如果填写了“*”,将允许用户访问所有资源;除非业务需要,否则请按照最小权限原则授予用户相应的访问权限范围。
            config.put("allowPrefix", "*");
            // 密钥的权限列表。简单上传、表单上传和分片上传需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
            String[] allowActions = new String[] {
                    // 简单上传
                    "name/cos:PutObject",
                    // 表单上传、小程序上传
                    "name/cos:PostObject",
                    // 分片上传
                    "name/cos:InitiateMultipartUpload",
                    "name/cos:ListMultipartUploads",
                    "name/cos:ListParts",
                    "name/cos:UploadPart",
                    "name/cos:CompleteMultipartUpload"
            };
            config.put("allowActions", allowActions);
            JSONObject credential = CosStsClient.getCredential(config);
            //成功返回临时密钥信息,如下打印密钥信息
            logger.debug("credential:="+credential);
            atx.setStringValue("AUTH_DATA", credential.toString());
        } catch (Exception e) {
            //失败抛出异常
            throw new IllegalArgumentException("no valid secret !");
        }
		return 1;
	}

结束:

以上就是主小程序端及java端代码。
请注意:针对小程序和普通页面,cos有两套js,请勿混。
使用微信jssdk和小程序sdk,上传到腾讯云的COS,具有天然的同一体系的优势,一家人不说两家话,上传对象(图片、视频)到cos,不必再经过本地应用服务器,减少了对服务端的压力(带宽和内存),也免去了自己实现:上传的视频和图片压缩过程,服务端只存对象的路径即可。

其他,待补充… …

参考,感谢:
[1]: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
[2]: https://cloud.tencent.com/document/product/436/31953

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐