03-使用COS上传文件

小程序一般是前后端分离的开发,图片等静态资源就存放在资源服务器中。本小节学习如何使用腾讯云上传文件

小程序上传文件界面

03-使用COS上传文件

03-使用COS上传文件

小程序wxml和wxss以及js文件

<button bindtap="uploadImage">请上传图片</button>
<view class="container">
  <image wx:for="{{imageList}}" src="{{item}}"></image>
</view>
<button bindtap="uploadFile">点击上传</button>

.container image{
  width: 200rpx;
  height: 200rpx;
  padding: 5rpx;
}

.container{
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

 uploadImage:function(){
    var that = this;

    wx.chooseImage({
      count:9,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success:function(res){
        // 默认图片 + 选择的图片; 
        that.setData({
          imageList: that.data.imageList.concat(res.tempFilePaths)
        });
      }
    });
  },

COS

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

03-使用COS上传文件

03-使用COS上传文件

03-使用COS上传文件

捡最便宜的购买,只是用于测试而已,另外新用户有50G的免费空间,我已经申请过了,现在找不到入口,你们自己找一找

准备工作

1. 创建存储桶

03-使用COS上传文件

03-使用COS上传文件

03-使用COS上传文件

03-使用COS上传文件

03-使用COS上传文件

03-使用COS上传文件

2. 小程序配置合法域名

03-使用COS上传文件

将之前配置的桶域名放在这儿。

小程序端上传文件

1. 手动安装

小程序SDK

按照文档要求来进行安装测试

复制源码文件中的 cos-wx-sdk-v5.js 到自己小程序代码根目录下任意路径,并用相对路径引用:

var COS = require('../../utils/cos-wx-sdk-v5.js')

npm 安装

如果小程序代码使用了 webpack 打包,则通过 npm 安装依赖即可:

npm install cos-wx-sdk-v5

其中小程序代码使用var COS = require('cos-wx-sdk-v5');进行引用。

这里我们使用复制源码创建对应的文件的方法

03-使用COS上传文件

使用的时候一定要使用相对路径

2. 配置白名单

准备工作中已经讲过了

3. 触发选择图片并且显示

03-使用COS上传文件

先给按钮绑定一个uploadImage事件

<button bindtap="uploadImage">请上传图片</button>
<view class="container">
  <image wx:for="{{imageList}}" src="{{item}}"></image>
</view>
<button bindtap="uploadFile">点击上传</button>

js响应事件,并且将图片显示出来

// pages/publish/publish.js
var COS = require('../../utils/cos-wx-sdk-v5.js')

Page({

  /**
   * 页面的初始数据
   */
  data: {
    imageList: [] //将要显示的图片列表
  },

  uploadImage:function(){
    var that = this;

    wx.chooseImage({
      count:9,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success:function(res){
        //图片可以多次选择,但是这次选择的不可覆盖上次选择的。
        // 默认图片 + 选择的图片; 
        that.setData({
          imageList: that.data.imageList.concat(res.tempFilePaths)
        });
      }
    });
  },
})

4. 上传图片

小程序上传文件SDK

上传文件首先需要生成上传文件的对象,该对象初始化参数需要秘钥,围绕秘钥,官方文档给出了四种初始化方式。

  • 格式一(推荐):后端通过获取临时密钥给到前端,前端计算签名。
  • 格式二(推荐):细粒度控制权限,后端通过获取临时密钥给到前端,前端只有相同请求才重复使用临时密钥,后端可以通过 Scope 细粒度控制权限。
  • 格式三(不推荐):前端每次请求前都需要通过 getAuthorization 获取签名,后端使用固定密钥或临时密钥计算签名返回给前端。该格式分块上传权限不易控制,不推荐您使用此格式。
  • 格式四(不推荐):前端使用固定密钥计算签名,该格式适用于前端调试,若使用此格式,请避免泄露密钥。

我们先来测试文件是否可以上传,因此先用格式四。

上传图片页面的js完整代码

// 导入我们创建的SDK文件
var COS = require('../../utils/cos-wx-sdk-v5.js')

Page({
  data: {
    imageList: []//展示选中的图片
    onlineImageList:[]// 文件上传成功后,接口会给我们返回一个文件路径
  },

  // 选择图片函数
  uploadImage:function(){
    var that = this;
    
    wx.chooseImage({
      count:9,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success:function(res){
        // 默认图片 + 选择的图片; 
        that.setData({
          imageList: that.data.imageList.concat(res.tempFilePaths)
        });
      }
    });
  },

  // 上传文件的函数
  uploadFile:function(){
    var onlineImageList = [];
    var that = this;
    var cos = new COS({
      SecretId: '你的腾讯云APISecretId', //这一块不懂可以看同系列博客 01_python+腾讯云发送短信
      SecretKey: '你的腾讯云APISecretKey',
    });
    // 循环异步上传图片,从imageList中取出完整的包含路径的文件名
    for(var index in this.data.imageList){
      var filePath = this.data.imageList[index];
      cos.postObject({
        Bucket: 'one-1303927750', // 你配置的桶名
        Region: 'ap-guangzhou',   // 你配置的对象存储服务的域
        Key: index + "uuu.png",   // 放到服务器上时的文件名,自己配置可以避免文件重复,一旦文件重复就会形成覆盖
        FilePath: filePath,       // 完整的文件名
        onProgress: function (info) { // 上传过程中返回的信息,可以用于只做进度条
          console.log('进度条', JSON.stringify(info));
        }
      }, function (err, data) {
        // onlineImageList.push(data.Location);
        console.log(data)
      });
    }
    
  },
})

如果微信小程序开发者工具的控制台打印出了返回信息,则说明上传成功,另外也可以在控制台查看文件上传情况

03-使用COS上传文件

改进文件上传

上面的文件上传使用的是固定秘钥,这个秘钥卸载了小程序文件中,也就是说使用这个小程序的人都能获取秘钥,不安全,腾讯云支持使用临时秘钥,也就是上述的四种上传格式中的前三个。

腾讯云推荐第一个第二种方式,此处我们使用第一种方式来演示

var cos = new COS({
    // 必选参数
    getAuthorization: function (options, callback) {
        wx.request({
            url: 'http://127.0.0.1:8000/api/upLoadFile',//这里我们使用django后端来生成临时秘钥返回前端,让前端生成cos上传文件对象
            data: {
                // 可从 options 取需要的参数
            },
            success: function (result) {
                var data = result.data;
                var credentials = data && 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
                });
            }
        });
    }
});

官方后端生成临时秘钥指引

Web、iOS、Android 使用 COS 时,通过固定密钥计算签名方式不能有效地控制权限,同时把永久密钥放到客户端代码中有极大的泄露风险。如若通过临时密钥方式,则可以方便、有效地解决权限控制问题。
例如,在申请临时密钥过程中,可以通过设置权限策略 policy 字段,限制操作和资源,将权限限制在指定的范围内。

1. 安装python模块
django想要生成临时秘钥返回给前端,需要先安装模块

pip install -U qcloud-python-sts

python生成临时秘钥示例代码

我们把这段代码修改到django中,本次Django使用DRF来响应请求

添加一个请求

from django.urls import re_path, include
from api import views

urlpatterns = [
    re_path(r'^credential/', views.CredentialView.as_view())
]

响应视图类

import os
from sts.sts import Sts
import json

from rest_framework.views import APIView
from rest_framework.response import Response

from paimai import settings


class CredentialView(APIView):
    def get(self, request, *args, **kwargs):

        config = {
            'url': settings.TENCENT_STS_URL,
            # 域名,非必须,默认为 sts.tencentcloudapi.com
            'domain': settings.TENCENT_STS_DOMAIN,
            # 临时密钥有效时长,单位是秒
            'duration_seconds': settings.TENCENT_STS_DURATION_SECONDS,
            'secret_id': settings.TENCENT_SECRET_ID,
            # 固定密钥
            'secret_key': settings.TENCENT_SECRET_KEY,
            # 设置网络代理
            # 'proxy': {
            #     'http': 'xx',
            #     'https': 'xx'
            # },
            # 换成你的 bucket
            'bucket': settings.TENCENT_STS_BUCKET,
            # 换成 bucket 所在地区
            'region': settings.TENCENT_CITY,
            # 这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径
            # 例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
            'allow_prefix': '*',
            # 密钥的权限列表。简单上传和分片需要以下的权限,其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
            'allow_actions': [
                # 简单上传
                # 'name/cos:PutObject',
                # 这里我只测试上传,仅保留这一个权限即可
                'name/cos:PostObject',
                # 分片上传
                # 'name/cos:InitiateMultipartUpload',
                # 'name/cos:ListMultipartUploads',
                # 'name/cos:ListParts',
                # 'name/cos:UploadPart',
                # 'name/cos:CompleteMultipartUpload'
            ],

        }

        try:
            sts = Sts(config)
            response = sts.get_credential()
            print(response)
            return Response(response)
        except Exception as e:
            print(e)

可以看到我的试图响应类中使用了很多全局变量,因此还要在django的配置文件中添加全局变量

配置全局变量

# ############################# 腾讯云 #############################
TENCENT_SECRET_ID = "AKIDjGWVDfqkNkpdAPP9cokPmshGYYHjvpSp"
TENCENT_SECRET_KEY = "7xTkjSv61f27wTjiQr1uWsxlHXVDeohI"
TENCENT_CITY = "ap-guangzhou"
TENCENT_STS_URL = 'https://sts.tencentcloudapi.com/'
TENCENT_STS_DOMAIN = 'sts.tencentcloudapi.com'
TENCENT_STS_DURATION_SECONDS = 1800
TENCENT_STS_BUCKET = 'one-1303927750'

修改小程序请求临时秘钥

// pages/publish/publish.js
var COS = require('../../utils/cos-wx-sdk-v5.js')

Page({

  /**
   * 页面的初始数据
   */
  data: {
    imageList: [],
    onlineImageList:[],
  },

  uploadImage:function(){
    var that = this;

    wx.chooseImage({
      count:9,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'],
      success:function(res){
        // 设置imageList,页面上图片自动修改。
        // that.setData({
        //   imageList: res.tempFilePaths
        // });

        // 默认图片 + 选择的图片; 
        that.setData({
          imageList: that.data.imageList.concat(res.tempFilePaths)
        });
      }
    });
  },

  uploadFile:function(){
    var onlineImageList = [];
    var that = this;
    //新的创建cos对象的方式
    // 去某个地方获取一个临时密钥
    var cos = new COS({
      getAuthorization: function (options, callback) {
        // 服务端 JS 和 PHP 示例:https://github.com/tencentyun/cos-js-sdk-v5/blob/master/server/
        // 服务端其他语言参考 COS STS SDK :https://github.com/tencentyun/qcloud-cos-sts-sdk
        // STS 详细文档指引看:https://cloud.tencent.com/document/product/436/14048
        wx.request({
          url: 'http://127.0.0.1:8000/api/credential/',
          data: {
            // 可从 options 取需要的参数
          },
          success: function (result) {
            var data = result.data;
            var credentials = data.credentials;
            callback({
              TmpSecretId: credentials.tmpSecretId,
              TmpSecretKey: credentials.tmpSecretKey,
              XCosSecurityToken: credentials.sessionToken,
              ExpiredTime: data.expiredTime,
            });
          }
        });
      }
    });

    for(var index in this.data.imageList){
      var filePath = this.data.imageList[index];
      cos.postObject({
        Bucket: 'one-1303927750',
        Region: 'ap-guangzhou',
        Key: index + "uuu.png",
        FilePath: filePath,
        onProgress: function (info) {
          console.log('进度条', JSON.stringify(info));
        }
      }, function (err, data) {
        // onlineImageList.push(data.Location);
        console.log(data)
      });
    }
  },

})

微信开发者工具控制台打印

03-使用COS上传文件

腾讯云文件存储后端

03-使用COS上传文件

文件上传成功。

上一篇:【操作】window10 安装.net framework 2.0插件


下一篇:简单的动画效果的函数封装