OSS提供JS SDK方式可以让用户直接在前端页面中嵌入js包直接操作OSS,但是该方式操作OSS最容易出现的问题即是AccessKeyId和AccessKeySecret的泄露导致被恶意访问的情况。因此提供了STS的方式动态获取token操作OSS,随之而来带来了整个业务逻辑的复杂度。今天在这里给大家介绍STS方式进行断点续传的实践方法。

基本概念

1. OSS Javascript SDK
OSS提供了海量、安全、低成本、高可靠的云存储服务,因此该产品最基本的功能即是实现将客户端的资源上传至OSS。OSS底层提供了与平台无关的RESTful API接口,但是该接口需要用户自行实现拼接发到OSS服务器的请求包以及签名参数,对于客户的技术水平提出了较高的要求。
因此OSS提供了各种语言的SDK帮助用户较方便的接入OSS并实现与OSS服务器端的对接操作,详细的SDK列表请参考 OSS SDK 列表,其中绝大多数的SDK均是服务器端的SDK,是无法直接在前端页面中使用的。而Javascript SDK包括浏览器应用和node.js两种方式,浏览器应用即可以实现前端页面直接操作OSS,避免增加应用服务器的负载压力。

2. 断点续传功能
在OSS上传资源的场景中经常会遇到以下场景导致上传失败等问题,对于用户体验较差:

  • 上传超过100MB大小的文件;
  • 网络条件较差,和OSS的服务器之间的链接经常断开;
  • 上传文件需要实时掌握上传进度;
  • 业务逻辑需要断点续传。

因此OSS提供了断点续传的方法帮助用户改善该场景。断点续传的方法主要是通过checkpoint和分块上传的接口实现的断点续传。
分块上传是SDK将用户待上传的完整文件分成若干个分片后分别上传,然后上传完成后验证各个分块的etag保证数据正确性后进行合并完成的。因此分块上传的逻辑主要包括:
InitiateMultipartUpload(生成UploadId并设置Object的HTTP头)->UploadPart(上传分块,可并行上传)->CompleteMultipartUpload(根据part列表验证每个part的有效性后合并为完整的Object)。
断点续传即是在progress参数中将断点信息抛出记录在checkpoint变量中。后续续传时即将之前记录的checkpoint信息重新传入multipartUpload接口即可以实现,对应的demo请参考:

var co = require('co');
var OSS = require('ali-oss')
var client = new OSS({region: '<Your region>',accessKeyId: '<Your AccessKeyId>',accessKeySecret: '<Your AccessKeySecret>',bucket: 'Your bucket name'
});
co(function* () {var checkpoint;// retry 5 timesfor (var i = 0; i < 5; i++) {var result = yield client.multipartUpload('object-key', 'local-file', {checkpoint: checkpoint,progress: function* (percentage, cpt) {checkpoint = cpt;}});console.log(result);break; // break if success} catch (err) {console.log(err);}}
}).catch(function (err) {console.log(err);
});

注意:Javascript sdk对于上述的三个部分做了封装,因此对于用户来讲不需要分步操作,而仅需要统一调用multipartUpload接口即可实现。

3. STS的Token功能
OSS SDK均需要通过AccesssKeyId和AccessKeySecret授权后才可以访问OSS,而AccesssKeyId和AccessKeySecret包括三种方式,分别是:

  • 主账号AccesssKeyId和AccessKeySecret;
  • 子账号AccesssKeyId和AccessKeySecret;
  • STS动态生成的AccesssKeyId和AccessKeySecret和AccessKeyToken。

其中前两种方式对应的参数均是固定的,如果直接写在前端页面中会导致泄露的风险导致OSS被恶意操作;而第三种STS动态生成的Token则具有时间戳,仅有在时间戳有效时间内才可以使用。能够提升用户操作安全性。
STS的token一般可以前端代码向应用服务器请求得到结果,也可以使用JS SDK直接操作,demo请参考:

var OSS = require('ali-oss');
var STS = OSS.STS;
var co = require('co');
var sts = new STS({accessKeyId: '<子账号的AccessKeyId>',accessKeySecret: '<子账号的AccessKeySecret>'
});
co(function* () {var token = yield sts.assumeRole('<role-arn>', '<policy>', '<expiration>', '<session-name>');var client = new OSS({region: '<region>',accessKeyId: token.credentials.AccessKeyId,accessKeySecret: token.credentials.AccessKeySecret,stsToken: token.credentials.SecurityToken,bucket: '<bucket-name>'});
}).catch(function (err) {console.log(err);
});

注意:使用STS的token创建OSSClient对象必须同时提供accessKeyId、accessKeySecret和stsToken,否则将报错。

JS SDK使用STS方式实现断点续传

STS的token有时间戳,当超过时间戳会导致后续的请求将无法正常请求,在断点续传时就可能出现当token已经过期后仍然需要上传的操作。为解决该问题我们建议在multipartUpload抛出的yichan异常中获取该异常重新获取token进行续传。最佳实践的代码请参考:

<!DOCTYPE html>
<html>
<head><script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-4.10.0.min.js"></script>
</head>
<body><input type="file" id="uploadFile" /><script type="text/javascript">stsAccessKeyId = ""stsAccessKeySecret = ""stsToken = ""var checkpoint_temp;function multipartUploadWithSts(storeAs, file, cpt) {OSS.urllib.request("http://localhost/sts-server/sts.php", {method: 'GET'}, function (err, response) {if (err) {return alert(err);}try {result = JSON.parse(response);} catch (e) {errmsg = 'parse sts response info error: ' + e.message;return alert(errmsg);}console.log(result)client = new OSS.Wrapper({accessKeyId: result.AccessKeyId,accessKeySecret: result.AccessKeySecret,stsToken: result.SecurityToken,bucket: 'dongchics',endpoint: 'http://oss-cn-hangzhou.aliyuncs.com'});multitest(client, storeAs, file, cpt);})};var upload = function () {var client = null;var file = document.getElementById('uploadFile').files[0];console.log(file);var storeAs = file['name'];console.log("upload file=",file)multipartUploadWithSts(storeAs, file)};function multitest (ossClient, storeAs, file, cpt) {//console.log(file.name + ' => ' + storeAs);var checkpoint_temp;if (cpt) {console.log("multitest with cpt")ossClient.multipartUpload(storeAs, file,{parallel: 2,checkpoint: cpt,progress: function* (percent, cpt) {console.log('Progress: ' + percent);checkpoint_temp = cpt}}).then(function (result) {console.log(result);}).catch(function (err) {console.log(err);multipartUploadWithSts(storeAs, file, checkpoint_temp)});} else {console.log("multitest without cpt")ossClient.multipartUpload(storeAs, file,{parallel: 2,progress: function* (percent, cpt) {console.log('Progress: ' + percent);checkpoint_temp = cpt}}).then(function (result) {console.log(result);}).catch(function (err) {console.log(err);multipartUploadWithSts(storeAs, file, checkpoint_temp)});}};document.getElementById('uploadFile').onchange = upload;</script>
</body>
</html>

这段demo主要包括一下几部分:

1.前端向服务器端发起请求sts的token的请求用户初始化OSSClient对象。而服务器端收到该请求后返回AccessKeyId、AccessKeySecret、SecurityToken和Expiration,这里使用的STS的php sdk实现的,代码可以参考:

<?phpinclude_once 'aliyun-php-sdk-core/Config.php';use Sts\Request\V20150401 as Sts;function read_file($fname){$content = '';if (!file_exists($fname)) {echo "The file $fname does not exist\n";exit (0);}$handle = fopen($fname, "rb");while (!feof($handle)) {$content .= fread($handle, 10000);}fclose($handle);return $content;}$content = read_file('./config.json');$myjsonarray = json_decode($content);$accessKeyID = $myjsonarray->AccessKeyID;$accessKeySecret = $myjsonarray->AccessKeySecret;$roleArn = $myjsonarray->RoleArn;$tokenExpire = $myjsonarray->TokenExpireTime;$policy = read_file($myjsonarray->PolicyFile);$iClientProfile = DefaultProfile::getProfile("cn-hangzhou", $accessKeyID, $accessKeySecret);$client = new DefaultAcsClient($iClientProfile);$request = new Sts\AssumeRoleRequest();$request->setRoleSessionName("client_name");$request->setRoleArn($roleArn);$request->setPolicy($policy);$request->setDurationSeconds($tokenExpire);$response = $client->doAction($request);$rows = array();$body = $response->getBody();$content = json_decode($body);$rows['status'] = $response->getStatus();if ($response->getStatus() == 200){$rows['AccessKeyId'] = $content->Credentials->AccessKeyId;$rows['AccessKeySecret'] = $content->Credentials->AccessKeySecret;$rows['Expiration'] = $content->Credentials->Expiration;$rows['SecurityToken'] = $content->Credentials->SecurityToken;}else{$rows['AccessKeyId'] = "";$rows['AccessKeySecret'] = "";$rows['Expiration'] = "";$rows['SecurityToken'] = "";}echo json_encode($rows);return;
?>

2.在multitest方法中实现断点续传,其中cpt用来判断是否已有断点信息,如果没有该信息则初始分块上传方法,并将断点信息存放在checkpoint_temp变量中;如果有该信息则会将checkpoint_temp作为参数传入multipartUpload方法。

3.在catch异常中重复调用断点续传方法以保证token过期后继续上传。

注意:JS SDK封装的multipartUpload接口实现了并行分块上传,因此当第一个由于token过期出现的403错误后并不会立刻catch到该err,而是需要一段时间才可以捕获该异常,实际测试其延迟在网速正常的情况下为秒级或者分钟级别。

【OSS 最佳实践】JS SDK使用STS方式实现断点续传相关推荐

  1. MSSQL · 最佳实践 · RDS SDK实现数据库迁移上阿里云RDS SQL Server

    title: MSSQL · 最佳实践 · RDS SDK实现数据库迁移上阿里云RDS SQL Server author: 风移 摘要 至今,我们完成了SQL Server备份还原专题系列七篇月报分 ...

  2. 信创办公--基于WPS的Word最佳实践系列(图文环绕方式)

    信创办公–基于WPS的Word最佳实践系列(图文环绕方式) 1. 项目背景 Word中涉及到文字与图片的排版时,各种图片与文字的组合效果,能使页面内容更加清楚.美观,灵活. 2. 打开布局选项中图文环 ...

  3. 第3.1.1章 WEB系统最佳实践 js控件之slimScroll的使用

    漂亮的虚拟滚动条,slimScroll下载地址 $(function() {$(".slimscroll").slimScroll({width: 'auto', //可滚动区域宽 ...

  4. 蚂蚁区块链第15课 JS SDK概述及API接口速查

    1,摘要 本文讲解蚂蚁BAAS的JavaScript SDK概述,说明JS SDK对应的API接口速查.其他语言包SDK参考官网其他章节说明即可. 2,JS SDK 说明 JavaScript SDK ...

  5. 信创办公--基于WPS的Word最佳实践系列(汇总目录)

    信创办公–基于WPS的Word最佳实践系列(汇总目录) 本系列基于WPS的Word进行最佳实践讲解,欢迎大家学习查看哦~ 信创办公–基于WPS的Word最佳实践系列(目录的插入及更新) 信创办公–基于 ...

  6. 【线上分享】全球多媒体视频内容保护最佳实践

    随着后疫情时代教育全面转向线上.短视频和影视剧市场需求增加,音视频平台对于内容保护的重视更是前所未有.国内,5G的加持下,视频的消费蓬勃发展,用户付费习惯养成,如何增加和保护收益,成为各视频平台和在线 ...

  7. OSS brower js SDK

    浅谈 今天带来的是 OSS brower js SDK 的安装过程和使用的 demo 测试用例. 环境准备 OSS brower js SDK 是基于 node js 框架上的服务端程序,服务端启动以 ...

  8. React.js 2016 最佳实践 徬梓阅读 1584收藏 71

    为什么80%的码农都做不了架构师?>>>    译者按:近几个月React相关话题依旧火热,相信越来越多的开发者在尝试这样一项技术,我们团队也在PC和移动端不断总结经验.2016来了 ...

  9. Node.js CLI 工具最佳实践

    为什么写这篇文章? 一个糟糕的 CLI 工具会让用户觉得难用,而构建一个成功的 CLI 需要密切关注很多细节,同时需要站在用户的角度,创造良好的用户体验.要做到这些特别不容易. 在这个指南中,我列出了 ...

  10. 使用 Node.js Express 的最佳实践

    Production best practices: performance and reliability 本文讨论部署到生产的 Express 应用程序的性能和可靠性最佳实践. 这个话题显然属于& ...

最新文章

  1. SQLServer2005数据库自动备份
  2. ASP.NET 一般处理程序
  3. 获取php数组的键名和值
  4. 算法杂货铺——分类算法之贝叶斯网络(Bayesian networks)
  5. SQL SERVER大话存储结构(2)
  6. java csv 导出_java实现CSV文件输出
  7. CCNP-17 OSPF试验13(BSCI)
  8. 深入理解socket编程的几个函数和两种fd
  9. Node.js实现一个HTTP服务器
  10. python中sorted方法和列表的sort方法使用详解
  11. 四大门户金融业务接连中招,流量这把钥匙正被氧化
  12. 基于matlab雷达算法,基于MATLAB的雷达信号处理
  13. 语音增强论文翻译:2017_SEGAN: Speech Enhancement Generative Adversarial Network
  14. AECC2015官方破解补丁/AdobeAfterEffectsCC2015中文版免费下载(AE安装教程)
  15. python-优矿-期权合成期货策略
  16. David P.Williams论文系列 SAS图像分辨率与目标检测性能的关系
  17. (附源码)计算机毕业设计SSM旅游分享平台
  18. Gson系列1 --- Gson 序列化与反序列化 -- 数组 / 集合序列化
  19. GPS卫星计时周期清零,GPS周期翻转,GPS周期清零
  20. Kafka 核心原理(贼全面)

热门文章

  1. 一些Arduino 测试代码
  2. jquery 文字轮播
  3. c#中,如何获取日期型字段里的年、月、日?
  4. PAT——1054. 求平均值
  5. 数据库问题6-將系統資料表對應至系統檢視
  6. oracle导出大数据
  7. 深入理解计算机系统(1)--hello world程序的生命周期
  8. WebForm控件多字段绑定
  9. ASP.NET MVC 分部视图
  10. GPS核心技术--精确计时与原子钟