【无聊数学】uniapp直传腾讯云COS(云对象存储)

1.背景

时间碎片化是现代社会中一个普遍存在的问题,它给人们的生活和工作带来了许多挑战。

首先,时间碎片化导致了人们难以集中精力完成任务。在不断切换不同任务和应用程序的过程中,人们的注意力不断被分散,导致难以保持专注和高效。这不仅影响了工作效率,还可能导致工作质量下降。

其次,时间碎片化可能导致人们的压力和焦虑感增加。当人们感到自己的时间被切割成许多小块,无法掌控自己的生活和工作时,他们可能会感到不安和焦虑。这种情绪状态可能对人们的身心健康产生负面影响。

此外,时间碎片化还可能影响人们的创造力和思考能力。由于时间被分割成小块,人们可能没有足够的时间和空间进行深入的思考和创造性的工作。这可能会限制人们的创新能力和发展潜力。

然而,我们也要认识到时间碎片化是现代社会中不可避免的现象。随着科技的发展和生活节奏的加快,人们需要处理的信息和任务越来越多,时间碎片化也在所难免。因此,我们应该寻找有效的方法来应对时间碎片化带来的挑战。

为此,我们开发了一款数学益智应用--无聊数学。如果你感兴趣,可以直接微信打开。

同时,我们主张:

用数学打发无聊时间 

2.问题的产生

无聊数学中,用户可以提交自己的创意题目,也可以更新自己的图片,用户会上传图片,为了减少服务器的压力,我们设计上让app直接把图片上传到腾讯云的对象云存储COS,同时,也让整体技术方案更加简便。

3.如何解决问题

3.1 关于腾讯云对象云存储COS

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

COS 通过控制台、API、SDK 和工具等多样化方式简单、快速地接入,实现了海量数据存储和管理。通过 COS 可以进行任意格式文件的上传、下载和管理。腾讯云提供了直观的 Web 管理界面,同时遍布全国范围的 CDN/EdgeOne 节点可以对文件下载进行加速。

如果你的应用需要使用到对象存储,更多的细节,你可以访问腾讯云的对象云存储COS

3.2前端直传的过程

前端直传,本质就是向服务端发送一个PUT Object的请求,例如,以下就是最简单的Put Object请求:

PUT /exampleobject HTTP/1.1
Host: examplebucket-1250000000.cos.ap-beijing.myqcloud.com
Date: Fri, 10 Apr 2020 09:35:05 GMT
Content-Type: image/jpeg
Content-Length: 16
Content-MD5: 7o3pGNBWQBRbGPcPTDqmAg==
Authorization: q-sign-algorithm=sha1&q-ak=AKID8A0fBVtYFrNm02oY1g1JQQF0c3JO****&q-sign-time=1586511305;1586518505&q-key-time=1586511305;1586518505&q-header-list=content-length;content-md5;content-type;date;host&q-url-param-list=&q-signature=c4147d4d457869a49b13e8e936c06a12c809****
Connection: close

[Object Content]

向COS服务端发送一个Put Object的主要过程,分为两个步骤:

  1. 实现一个服务端接口,用于生成随机文件路径、计算签名,并返回给前端
  2. 前端直接发起upload的请求

3.3 服务器端计算签名

以下的例子就是一个serverless版本的云函数,在服务端已经运行通过。

const crypto = require('crypto');
const moment = require('moment');


let myHandler = async function (event, context, callback, logger) {
  logger.info(event);

  const ext = event.extName;

  // 配置参数
  var config = {
    // 获取腾讯云密钥,建议使用限定权限的子用户的密钥 https://console.cloud.tencent.com/cam/capi
    secretId: secretId,
    secretKey: secretKey,
    // 这里填写存储桶、地域,例如:test-1250000000、ap-guangzhou
    bucket: 'wuliaoshuxue-xx',
    region: 'ap-xxx',
    // 限制的上传后缀
    extWhiteList: ['jpg', 'jpeg', 'png', 'gif', 'bmp'],
  };

  // 生成要上传的 COS 文件路径文件名
  var generateCosKey = function (ext) {
    var ymd = moment().format('YYYYMMDD_HHmmss');
    var r1 = ('000000' + Math.random() * 1000000).slice(-6);
    var r2 = ('000000' + Math.random() * 1000000).slice(-6);
    var cosKey = `collect-question/${ymd}_${r1}_${r2}.${ext}`;
    return cosKey;
  };

  // 判断异常情况
  if (!config.secretId || !config.secretKey){

  }
  if (!config.bucket || !config.region){

  }
  if (!config.extWhiteList.includes(ext)){

  }
  // 开始计算凭证
  var cosHost = `${config.bucket}.cos.${config.region}.myqcloud.com`;
  var cosKey = generateCosKey(ext);
  var now = Math.round(Date.now() / 1000);
  var exp = now + 900;
  var qKeyTime = now + ';' + exp;
  var qSignAlgorithm = 'sha1';
  // 生成上传要用的 policy
  // PostObject 签名保护文档 https://cloud.tencent.com/document/product/436/14690#.E7.AD.BE.E5.90.8D.E4.BF.9D.E6.8A.A4
  var policy = JSON.stringify({
    'expiration': new Date(exp * 1000).toISOString(),
    'conditions': [
    // {'acl': query.ACL},
    // ['starts-with', '$Content-Type', 'image/'],
    // ['starts-with', '$success_action_redirect', redirectUrl],
    // ['eq', '$x-cos-server-side-encryption', 'AES256'],
      {'q-sign-algorithm': qSignAlgorithm},
      {'q-ak': config.secretId},
      {'q-sign-time': qKeyTime},
      {'bucket': config.bucket},
      {'key': cosKey},
    ]
  });

  // 步骤一:生成 SignKey
  var signKey = crypto.createHmac('sha1', config.secretKey).update(qKeyTime).digest('hex');

  // 步骤二:生成 StringToSign
  var stringToSign = crypto.createHash('sha1').update(policy).digest('hex');

  // 步骤三:生成 Signature
  var qSignature = crypto.createHmac('sha1', signKey).update(stringToSign).digest('hex');

  const result = {
    cosHost: cosHost,
    cosKey: cosKey,
    policy: Buffer.from(policy).toString('base64'),
    qSignAlgorithm: qSignAlgorithm,
    qAk: config.secretId,
    qKeyTime: qKeyTime,
    qSignature: qSignature,
    // securityToken: securityToken, // 如果 SecretId、SecretKey 是临时密钥,要返回对应的 sessionToken 的值
  };

  callback({
    code : 0,
    msg: 'success',
    result : result
  });
};

export { myHandler };

3.4 App端的操作

app端从调用云函数获取凭证之后,以下的代码就是发起put请求了。

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


async function upload(filePath, opt, callback) {
	var vm = this;
	var formData = {
		key: opt.cosKey,
		policy: opt.policy, // 这个传 policy 的 base64 字符串
		success_action_status: 200,
		'q-sign-algorithm': opt.qSignAlgorithm,
		'q-ak': opt.qAk,
		'q-key-time': opt.qKeyTime,
		'q-signature': opt.qSignature,
	};
	if (opt.securityToken) {
		formData['x-cos-security-token'] = formData.securityToken;
	}

	uni.uploadFile({
		url: 'https://' + opt.cosHost, //仅为示例,非真实的接口地址
		filePath: filePath,
		name: 'file',
		formData: formData,
		success: (res) => {
			console.log("uni.uploadFile success res: ", res);
			
			if (![200, 204].includes(res.statusCode)) return callback && callback(res);
			
			var fileUrl = getUploadUrl(opt);
			callback && callback(null, fileUrl);
		},
		error(err) {
			console.log("uni.uploadFile err : ", err);
			//
			callback && callback(err);
		},
	});
}

4.总结

本文描述了如何从前端直接发起PUT Object请求,将文件上传到腾讯云的对象云存储COS,不同的项目,具体情况不同,如要依据实际的情况选择不同的文件上传方案。

 5.无聊数学系列文章

无聊数学是我们开发的一款数字益智应用,本系列文章,都是介绍相关的移动开发技术以及服务端开端技术,如果你感兴趣,欢迎继续阅读。

【无聊数学】从零开始开发一个鸿蒙元服务

【无聊数学】总结一下我们在开发中踩到的那些坑儿

【无聊数学】uniapp直传腾讯云COS(云对象存储)

  • 27
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yeahforce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值