Javascript 作为当下最火的语言(之一),结合 OSS 能够创建出非常丰富的跨前后端的应用。现在, OSS 正式推出 Javascript SDK ,使用 OSS 的 前后端 同学 都 可以方便地使用。
首先,什么是 ES6 ?
其实ES6是最新版本的 ECMAScript ,也就是 Javascript 标准。
ECMAScript 6, also known as ECMAScript 2015, is the latest version of the ECMAScript standard. > ES6 is a significant update to the language...
ES6 包含了众多重要的更新,但是今天对我们最重要的就是Generator Function,因为它可以让我们用同步的方式写异步代码:
var creds = yield applySTSToken(); var client = new OSS(creds); var result = yield client.list(); console.log(result);
上面的代码包含了两个异步的操作,applySTSToken
和list
,如果没有 generator ,我们就需要在applySTSToken
的 callback 中做list
,然后在list
的 callback 中做log
,比如这样:
applySTSToken(function (creds) { var client = new OSS(creds); client.list(function (result) { console.log(result); }); });
如果上面的代码看起来也“还可以”的话,那么当异步操作多起来之后,再考虑错误处理的场景,代码将会变得非常复杂。不得不说 callback 很锻炼大脑,但是有高科技为什么不利用呢?
这看起来不错,但是如何实现的呢?这篇文章介绍了如何实现 Promise (这真是个好名字)。最关键的地方就是yield
让控制流跳转到其他代码执行,相应的事件(callback)发生时,通过next
让控制流回到上次yield
的地方继续执行,这样就达到了“异步非阻塞”的效果。
目前主流的 Chrome/Firefox 版本都已经支持 ES6 的大部分功能了。主流的 Safari 版本和移动端浏览器目前还不支持 ES6 ,但是我们后面会讲到如何做兼容性转换。
SDK 目前支持 OSS 的绝大部分功能,包括上传 /下载文件、分片上传、 Bucket 管理、文件管理等,常用的上传 /下载也有多样的玩法:
npm install ali-oss co
使用put
接口上传一个 Object :
var OSS = require('ali-oss'); var co = require('co'); var fs = require('fs'); var client = new OSS({ accessKeyId: 'access key id', accessKeySecret: 'access key secret', region: 'oss-cn-hangzhou', bucket: 'my-bucket', }); co(function* () { // put from local file yield client.put('file', '/tmp/x'); // put from Buffer yield client.put('buffer', new Buffer'hello world')); // put from Stream yield client.put('stream', fs.createReadStream('/tmp/x')); }).catch(function (err) { console.log(err); });
使用get
和getStream
方法下载文件:
co(function* () { // get as content var result = yield client.get('object'); console.log(result.content); // download as file yield client.get('object', '/tmp/x'); // pipe to stream yield client.get('object', fs.createWriteStream('/tmp/x')); // get as stream var result = yield client.getStream('object'); result.stream.pipe(fs.createWriteStream('/tmp/y')); }).catch(function (err) { console.log(err); });
使用putBucketLifecycle
等接口来设置 Bucket 的属性。注意,目前 OSS 不支持 Bucket 相关的跨域请求,所以在浏览器中不能使用 Bucket 的管理接口。
co(function* () { var result = yield client.putBucketLifecycle('bucket', 'region', [ { id: 'delete after one day', prefix: 'logs/', status: 'Enabled', days: 1 }, { prefix: 'logs2/', status: 'Disabled', date: '2022-10-11T00:00:00.000Z' } ]); }).catch(function (err) { console.log(err); });
SDK 的每个方法都可以设置和获取 HTTP Headers :
co(function* () { // set headers var result = yield client.put('object', '/tmp/x', { headers: { 'content-type': 'application/Javascript; charset=utf8' } }); // get headers console.log(result.res.headers); }).catch(function (err) { console.log(err); });
Browserify, Babel等优秀工具的出现,使得我们能够在前后端共用一套代码。 OSS Javascript SDK 基于 Node.js 开发,通过Browserify和Babel产生适用于浏览器的代码,使得 OSS Javascript SDK 同时支持在浏览器中和 Node.js 环境中使用。
用户在浏览器中使用 SDK 时,首先在<head>
标签中包含如下<script>
标签:
<script src="http://gosspublic.alicdn.com/aliyun-oss-sdk-4.1.4.min.js"></script>
就可以在代码中使用OSS
对象:
<script type="text/Javascript"> var client = new OSS({ region: '<oss region>', accessKeyId: '<Your accessKeyId(STS)>', accessKeySecret: '<Your accessKeySecret(STS)>', stsToken: '<Your securityToken(STS)>', bucket: '<Your bucket name>' }); OSS.co(function* () { var result = yield client.list({ 'max-keys': 10 }); console.log(result); }).catch(function (err) { console.log(err); }); </script>
注意:上面的代码中用OSS.co
代替co
,同样的,如果用到了Buffer
,也要使用OSS.Buffer
代替。browser.js中显示了 SDK 暴露给浏览器的全部对象。
我们提供一个demo,使用 OSS Javascript SDK 开发了一个浏览器应用,提供上传文件 /上传文本 /列出文件 /下载文件 四个功能,效果如下:
只需要在 SDK 的代码目录执行npm run build-dist
命令,就可以生成用于浏览器的 SDK lib :
git clone https://github.com/ali-sdk/ali-oss.git cd ali-oss npm install npm run build-dist # output # dist/aliyun-oss-sdk.js # dist/aliyun-oss-sdk.min.js
上述的例子中使用 SDK 的代码使用了function*
和yield
等 ES6 的特性,这在支持 ES6 的浏览器(主流版本的 Chrome/Firefox )中可以直接运行,若要用于更多的浏览器,则需要使用Browserify和Babel进行兼容性转换:
npm install -g browserify npm install babelify babel-preset-es2015 echo '{ "presets": ["es2015"] }' > .babelrc browserify app.js -t babelify > app-babel.js
转换后只需要在<script>
标签中包含转换后的代码文件即可:
<script src="app-babel.js"></script>
在 SDK 的开发过程中,每发布一个版本,我需要手动做以下几件事情:
aliyun-oss-sdk.min.js
发布到 cdn这么多步骤,不出错是几乎不可能的。所以我们使用git-extras和git-pre-hooks,让发布过程变成"All-in-One",具体参考package.json。
首先确保在 master 分支,然后 npm 依赖都安装好了:
git checkout master npm install
发布过程:
vi package.json and change "version" to 4.2.0 git changelog -n -t 4.2.0 git release 4.2.0
是不是如丝般顺滑?
1 clijiac 2016-01-29 16:21:23 +08:00 DOTA1 差评,应该放个 DOTA2 的图 |
![]() | 2 bdbai 2016-01-29 16:31:10 +08:00 via iPhone 没有用过阿里云 OSS ,但是把 ak 、 sk 都放前端真的好吗? |
3 rockuw OP ![]() @bdbai 前端使用的 AK 、 SK 是从应用服务器获取的临时密钥,请参考[阿里云 STS]( https://help.aliyun.com/document_detail/oss/practice/ram_guide/overview.html)。 |
![]() | 5 wbsdty331 2016-01-29 16:36:36 +08:00 先大再跳 |
![]() | 6 libook 2016-01-29 16:50:54 +08:00 题主写的不错,支持一个。 学 ES6,我看的是这个 http://es6.ruanyifeng.com/ 讲得很好。 用 Koa 做 API 的话自带深度 co , Mongoose 等包自带 Promise ,没有 Promise 的话 ES6 也原生支持 Promise 了,只需要 new Promise(function(resolve,reject){/* Code */}) |
![]() | 7 sox 2016-01-29 16:53:23 +08:00 ![]() @libook 再推荐一个更深度的 ES6 教程 http://exploringjs.com/es6 |
![]() | 9 nakupanda 2016-01-29 17:41:02 +08:00 旱地神牛 6 |
![]() | 10 magicdawn 2016-01-29 18:11:24 +08:00 嗯, 我觉得应该定下标准吧... 例如函数名, 怎么区分 callback 版 & Promise 版... 我觉得 bluebird 的 promisify 的 xxx 与 xxxAsync 非常不错, 值得实践... |
![]() | 13 rannnn 2016-01-29 18:29:09 +08:00 ![]() 说了半天不知道 OSS 是什么东西 |
![]() | 14 FrankFang128 2016-01-29 18:36:15 +08:00 via Android 已经 7 了 |
16 rockuw OP @FrankFang12 7 还没有发布哦 |
![]() | 18 Tankpt 2016-01-29 19:03:04 +08:00 用过。。挺不错的。 |
19 LukeXuan 2016-01-29 19:54:05 +08:00 ES6 大跳 |
20 CheungKe 2016-01-29 20:03:12 +08:00 被图吸引了,看了半天,标题当 |
21 hantsy 2016-01-29 21:15:34 +08:00 cool work |
![]() | 22 chemzqm 2016-01-30 07:58:06 +08:00 require('babel-polyfill'); 既然用了这个东西,能不能写到文档里?不然用户可能在页面上重复引用的,这玩意蛮大的 |