JavaScript作为当下最火的语言(之一),结合OSS能够创建出非常丰富的跨前后端的应用。现在,OSS正式推出JavaScript SDK,使用OSS的 前后端 同学 都 可以方便地使用。
OSS JavaScript SDK基于ali-oss开发,感谢@fengmk2和@dead-horse的指导,增加了许多功能并修复了一些bug,主要包括:
- 支持在浏览器环境中使用
- 支持分片上传(multipart)
- 支持STS临时授权
- 修复若干bug
详见:https://github.com/ali-sdk/ali-oss/blob/master/History.md#400–2016-01-22
ES6
首先,什么是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管理、文件管理等,常用的上传/下载也有多样的玩法:
- 上传本地文件
- 上传Buffer内容
- 流式上传
- 分片上传
- 下载到本地文件
- 流式下载
安装
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);
});
管理Bucket
使用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);
});
HTTP Headers
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开发了一个浏览器应用,提供上传文件/上传文本/列出文件/下载文件 四个功能,效果如下:
Build 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
Build用户代码
上述的例子中使用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的开发过程中,每发布一个版本,我需要手动做以下几件事情:
- 修改ChangeLog
- 修改package.json中的版本
- 生成版本的tag
- 生成dist/aliyun-oss-sdk.min.js
- 发布到npm
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
是不是如丝般顺滑?
- github(欢迎Star/Fork/PR): https://github.com/ali-sdk/ali-oss
- API文档:https://github.com/ali-sdk/ali-oss#summary
- SDK文档:https://help.aliyun.com/document_detail/oss/sdk/javascript-sdk/install.html
- 我自己写得爽,也希望把这种“爽”带给用户
- 如果需要支持IE10以下,可以使用这个SDK:https://github.com/aliyun-UED/aliyun-sdk-js
- 我不认为ES6是“不普通不常用”的技术
我刚提了个issue https://github.com/ali-sdk/ali-oss/issues/87 ,你们应该将核心API做成 async function, 返回 promise 的那种,这样可用范围更广,不限制用户如何使用。
个人观点,不对请指正。