前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信小程序上传图片到腾讯COS存储桶实战

微信小程序上传图片到腾讯COS存储桶实战

作者头像
加菲猫的VFP
发布2022-05-26 09:26:03
3.2K0
发布2022-05-26 09:26:03
举报
文章被收录于专栏:加菲猫的VFP加菲猫的VFP

作者:火种 最近为了实现在小程序上传图片到腾讯COS存储桶,把官方提供的demo,看了一遍又一遍,试了又试,错了又错,踏过一个又一个坑,终于从不懂,到懵懂,到懂。>.<,好累,在此过程就不赘述,直接开始,希望和我一样的小白也可能轻松用上腾讯COS存储桶。

对象存储(Cloud Object Storage,COS)是腾讯云提供的一种存储海量文件的分布式存储服务,用户通过控制台、API、SDK 和工具等多种方式可以简单、快速地接入COS,实现了海量数据存储和管理。如果只是简单地上传图片,不建议使用SDK方式,如果要对存储桶或图片进行操作,建议使用SDK方式。

我用的是前一种,不使用SDK简单地上传图片,实现流程:首先小程序发送请求到中间层安全凭证服务(Security Token Service,STS)获取临时密钥给到前端,接着前端计算签名,然后凭签名再将图片上传到腾讯COS存储桶。(临时密钥有效时间短(30min - 36h),适用于前端直传等临时授权场景,相比永久密钥,安全性更高。)

腾讯提供的STS服务有很多语言,我选了PHP。很方便,只要把sts.php代码中的secretId、secretKey、bucket、region改成自已存储桶的就可以。不过布置PHP服务费了我好长时间,碰到各种情况,归结起来原因就是PHP和运行库版本不一致的问题,最后我选了最新版本的PHP8.1.5和运行库MVC++2015-2022Redistribuable(X64)才布置成功。PHP服务的布置可以参考:

加菲猫注:这里可以用VFP写后端的签名,COS有前端直传和后端上传的两种模式。

https://www.jb51.net/article/120427.htm, PHP服务布置成功后把腾讯提供的sts.php,sts.js, qcloud-sdk-sts.php三个文件放在中间层的根目录wwwroot中,这样STS服务就可以用了。 小程序INDEX.JS的代码如下:

代码语言:javascript
复制
var CosAuth = require('../../lib/cos-auth');//cos-auth.js腾讯提供,不用修改。
var config = require('../../config');//config.js腾讯提供,改一下sts.php网址和Bucket和Region就可以。
var prefix = 'https://' + config.Bucket + '.cos.' + config.Region + '.myqcloud.com/';
var stsCache;
var camSafeUrlEncode=function (str) {
  return encodeURIComponent(str)
      .replace(/!/g, '%21')
      .replace(/'/g, '%27')
      .replace(/\(/g, '%28')
      .replace(/\)/g, '%29')
      .replace(/\*/g, '%2A');
};
// 获取临时密钥
var getCredentials=function (callback) {
  if (stsCache && Date.now() / 1000 + 30 < stsCache.expiredTime) {
      callback(stsCache.credentials);
      return;
  }
  wx.request({
      method: 'GET',
      url: config.stsUrl, // 服务端签名,
      dataType: 'json',
      success: function (result) {
          var data = result.data;
          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,
          })
      });
  });
};

Page({
  data: {
   filePath:""
  },

   // 上传文件
  uploadFile:function () {
        var filePath=this.data.filePath;
        //console.log(filePath)
        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) {
                        wx.showModal({title: '上传成功', content: url, showCancel: false});
                    } else {
                        wx.showModal({title: '上传失败', content: JSON.stringify(res), showCancel: false});
                    }
                    console.log(res.statusCode);
                    console.log(url);
                },
                fail: function (res) {
                    wx.showModal({title: '上传失败', content: JSON.stringify(res), showCancel: false});
                }
            });
            requestTask.onProgressUpdate(function (res) {
                console.log('正在进度:', res);
            });
        });
    },
chooseFile:function() {//打开图库,选择图片
      this.setData({ motto: "选择图片" }),
      wx.chooseImage({
          count: 3,//限制三张图片
          sizeType: ['original', 'compressed'],
          sourceType: ['album', 'camera'],
          success :res => {
          const tempFilePaths = res.tempFilePaths;            this.setData({filePath:tempFilePaths[0]})
          }
      })
  }
})

INDEX.WXML的代码如下:

代码语言:javascript
复制
<button bindtap="chooseFile">选择文件</button>
<button bindtap="uploadFile">上传文件</button>
<image style="width: 400px; height: 200px; background-color: #eeeeee;" mode="scaleToFill" src="{{filePath}}"></image>

运行效果如下:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 加菲猫的VFP 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档