评论

轻松实现小程序直接上传图片至腾讯云对象存储

轻松实现小程序直接上传图片至腾讯云对象存储

概念介绍

对象存储(Cloud Object Storage,COS)是腾讯云提供的一种存储海量文件的分布式存储服务,用户可通过网络随时存储和查看数据。腾讯云 COS 使所有用户都能使用具备高扩展性、低成本、可靠和安全的数据存储服务。

前期准备

  1. 登录腾讯云对象存储控制台创建存储桶,获取 Bucket(存储桶名称) 和 Region(地域名称)。
  2. 通过管理控制台的 密钥管理 获取您的项目 SecretId 和 SecretKey
  3. 下载对象存储SDK,至小程序对象存储gitHub项目目录下载https://github.com/tencentyun/cos-wx-sdk-v5/tree/master/demo/lib下的cos-auth.js文件,添加至项目目录

项目实践

一、引用
var CosAuth = require('cos-auth');//引入对象存储SDK
var config = require('../utils/api.js');//定义了项目的一些配置内容,例如存储桶名称、地区、请求域名等
var stsCache; //存储临时秘钥及秘钥过期时间内容

//定义上传接口
var uploadFile = function(filePath, cb) {
  // 请求用到的参数
  var prefix = 'https://' + config.Bucket + '.cos.' + config.Region + '.myqcloud.com/';

  // 对更多字符编码的 url encode 格式
  var camSafeUrlEncode = function(str) {
    return encodeURIComponent(str)
      .replace(/!/g, '%21')
      .replace(/'/g, '%27')
      .replace(/\(/g, '%28')
      .replace(/\)/g, '%29')
      .replace(/\*/g, '%2A');
  };

  // 获取临时密钥
  // 全局变量stsCache 存储临时秘钥及过期时间内容
  var getCredentials = function(callback) {
    //判断临时秘钥未过期
    if (stsCache && Date.now() / 1000 + 30 < stsCache.expiredTime) {
      callback(stsCache && stsCache.credentials);
      return;
    }
    //过期,服务器重新请求获取临时秘钥
    wx.request({
      method: 'GET',
      url: 'https://baidu.com/Api/Cos/getCosTempKeys', // 服务端签名,参考 server 目录下的两个签名例子
      dataType: 'json',
      success: function(result) {
        var data = result.data.result;
        var credentials = data.credentials;
        if (credentials) {
          stsCache = data
        } else {
          wx.showModal({
            title: '临时密钥获取失败',
            content: JSON.stringify(data),
            showCancel: false
          });
        }
        callback(stsCache && stsCache.credentials);
      },
      error: function(err) {
        wx.showModal({
          title: '临时密钥获取失败',
          content: JSON.stringify(err),
          showCancel: false
        });
      }
    });
  };

  // 计算签名
  var getAuthorization = function(options, callback) {
    getCredentials(function(credentials) {
      callback({
        XCosSecurityToken: credentials.sessionToken,
        Authorization: CosAuth({
          SecretId: credentials.tmpSecretId,
          SecretKey: credentials.tmpSecretKey,
          Method: options.Method,
          Pathname: options.Pathname,
        })
      });
    });
  };

  // 上传文件
  var uploadFile = function(filePath, cb) {
    var Key = filePath.substr(filePath.lastIndexOf('/') + 1); // 这里指定上传的文件名
    getAuthorization({
      Method: 'POST',
      Pathname: '/'
    }, function(AuthData) {
      var requestTask = wx.uploadFile({
        url: prefix,
        name: 'file',
        filePath: filePath,
        formData: {
          'key': Key,
          'success_action_status': 200,
          'Signature': AuthData.Authorization,
          'x-cos-security-token': AuthData.XCosSecurityToken,
          'Content-Type': '',
        },
        success: function(res) {
          var url = prefix + camSafeUrlEncode(Key).replace(/%2F/g, '/');
          if (res.statusCode === 200) {
            if (cb) {
              cb(url);
            }
          } else {
            wx.showModal({
              title: '上传失败',
              content: JSON.stringify(res),
              showCancel: false
            });
          }
        },
        fail: function(res) {
          wx.showModal({
            title: '上传失败',
            content: JSON.stringify(res),
            showCancel: false
          });
        }
      });
      requestTask.onProgressUpdate(function(res) {
      });
    });
  };
  
  // 触发上传文件方法,按步骤调用执行
  uploadFile(filePath, cb);
};
module.exports = {
  uploadFile
};
2、调用以上SDK实现上传

1、 在需调用的文件,首先引入以上文件
var demoNoSdk = require(‘sdk文件路径’);//引入上述的对象存储SDK文件
2、 获取到上传文件的临时路径(备注:可以是直接调用wx.chooseImag方法获取的临时文件,也可以是调用wx.canvasToTempFilePath将画布导出的临时图片路径等等其他方式获取的到的临时图片文件路径)
这里调用wx. chooseImage为例

wx.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'], 
      sourceType: ['album', 'camera'], 
      success: function(res) {
//临时文件路径
       var tempFilePath= res.tempFilePaths[0]; 

   //定义上传图片成功后的回调函数
   var callback = function(url) {
//url为上传至对象存储成功后返回的云存储文件路径
//do other something
……
      };
//调用对象存储SDK,实现文件上传
//传递参数临时文件路径及上传成功后的回调函数,若不需要回调可不传此参数
       demoNoSdk.uploadFile(tempFilePath, callback);
      },
})

实现上传的过程如下

获取图片临时文件路径
->调用SDK的uploadFile方法
->服务器请求获取请求对象存储功能所需要的临时秘钥(并将秘钥结果及过期时间存储至全局变量,方便后面直接调用已缓存的未过期的临时秘钥即可,无需重复请求服务器获取)
->调用wx.uploadFile接口上传图片
->上传成功后调用我们自定义的回调函数实现我们自己的业务。

至此,小程序直接上传图片至对象存储完成!

最后一次编辑于  2019-04-27  
点赞 4
收藏
评论

5 个评论

  • 一念之间
    一念之间
    2019-09-16

    这个接口是什么?我返回的是一个页面取不到credentials

    2019-09-16
    赞同 1
    回复 3
    • 痛快科技
      痛快科技
      2019-09-17

      看一下腾讯云的对象存储文档,需要先获取一个密钥,密钥是自己腾讯云账号的,这个地址是一个示例,无法访问的

      2019-09-17
      回复
    • 一念之间
      一念之间
      2019-09-17回复痛快科技
      嗯嗯,这个是需要后端写个接口返回的吧
      2019-09-17
      1
      回复
    • 痛快科技
      痛快科技
      2019-09-17回复一念之间
      嗯嗯
      2019-09-17
      1
      回复
  • 一念之间
    一念之间
    2019-09-16

    该文件内容中的字段可以分享出来吗

    2019-09-16
    赞同 1
    回复 3
    • 痛快科技
      痛快科技
      2019-09-16
      只是定义了bucket和region,替换你申请的信息就可以了
      2019-09-16
      1
      回复
    • 一念之间
      一念之间
      2019-09-16回复痛快科技
      好的
      2019-09-16
      1
      回复
    • 一念之间
      一念之间
      2019-09-16回复痛快科技
      大神还在吗回答一下呗
      2019-09-16
      1
      回复
  • Nice
    Nice
    03-26

    上传图片的时候,可以修改上传图片的名字吗 现在上传的名字太长了 腾讯返回的名字要拿来存储 也太长了

    03-26
    赞同
    回复
  • 、、、
    、、、
    01-01

    腾讯云对象存储 价格有点贵

    01-01
    赞同
    回复 3
    • 痛快科技
      痛快科技
      01-02
      主要还是实现小程序变现,整体费用比自己做服务低,性价比高
      01-02
      回复
    • 、、、
      、、、
      01-02回复痛快科技
      如果文件私有每次访问都要生成一个新的地址,如果公开又不安全,公开了有人会不会有人恶意下载。到时候流量费也要不少
      01-02
      回复
    • 痛快科技
      痛快科技
      01-03
      在小程序内还好,文件链接一般人拿不到
      01-03
      回复
  • 罗梅光
    罗梅光
    2019-11-06

    收藏下。近期会用到。

    2019-11-06
    赞同
    回复
登录 后发表内容