Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
smallos edited this page Mar 3, 2016 · 1 revision

Welcome to the nodejs-sdk.v6 wiki! 概述

该 SDK 适用于 Node.js 0.4.7 及其以上版本,基于 七牛云存储官方API 构建。 若您的服务端是一个基于 Node.js 编写的网络程序,使用此 SDK , 能让您以非常便捷地方式将数据安全地存储到七牛云存储上。 以便让您应用的终端用户进行高速上传和下载,同时也使得您的服务端更加轻盈。

Node.js SDK 主要包含对七牛云存储API的包装,遵循qiniu sdkspec 涉及到以下几个方面:

服务端操作,生成上传授权(uptoken),私有bucket下载URL(downloadUrl),文件操作授权 客户端操作,上传文件(qiniu/io.js) 文件管理(qiniu/rs.js) 数据处理(qiniu/fop.js) 公共库(qiniu/rpc.js, qiniu/util.js)

准备开发环境

环境依赖

适用于 Node.js 0.4.7 及其以上版本

安装

通过 npm 以 node 模块化的方式安装: npm install qiniu

ACCESS_KEY 和 SECRET_KEY

在使用SDK 前,您需要拥有一对有效的 AccessKey 和 SecretKey 用来进行签名授权。

可以通过如下步骤获得:

开通七牛开发者帐号 登录七牛开发者自助平台,查看 AccessKey 和 SecretKey 。

使用SDK

初始化环境

对于服务端而言,常规程序流程是:

qiniu.conf.ACCESS_KEY = '' qiniu.conf.SECRET_KEY = '' 服务端操作时请务必初始化这两个变量

上传文件

为了尽可能地改善终端用户的上传体验,七牛云存储首创了客户端直传功能。一般云存储的上传流程是:

客户端(终端用户) => 业务服务器 => 云存储服务 这样多了一次上传的流程,和本地存储相比,会相对慢一些。但七牛引入了客户端直传,将整个上传过程调整为:

客户端(终端用户) => 七牛 => 业务服务器 客户端(终端用户)直接上传到七牛的服务器,通过DNS智能解析,七牛会选择到离终端用户最近的ISP服务商节点,速度会比本地存储快很多。文件上传成功以后,七牛的服务器使用回调功能,只需要将非常少的数据(比如Key)传给应用服务器,应用服务器进行保存即可。

上传流程

在七牛云存储中,整个上传流程大体分为这样几步:

业务服务器颁发 上传凭证给客户端(终端用户) 客户端凭借 上传凭证 上传文件到七牛 在七牛获得完整数据后,发起一个 HTTP 请求回调到业务服务器 业务服务器保存相关信息,并返回一些信息给七牛 七牛原封不动地将这些信息转发给客户端(终端用户) 需要注意的是,回调到业务服务器的过程是可选的,它取决于业务服务器颁发的 上传凭证。如果没有回调,七牛会返回一些标准的信息(比如文件的 hash)给客户端。如果上传发生在业务服务器,以上流程可以自然简化为:

业务服务器生成 uptoken(不设置回调,自己回调到自己这里没有意义) 凭借 上传凭证 上传文件到七牛 善后工作,比如保存相关的一些信息

上传策略 上传凭证 实际上是用 AccessKey/SecretKey 进行数字签名的上传策略(rs.PutPolicy),它控制着整个上传流程的行为。让我们快速过一遍你都能够决策啥:

function PutPolicy(scope, callbackUrl, callbackBody, returnUrl, returnBody, asyncOps, endUser, expires) { this.scope = scope || null; this.callbackUrl = callbackUrl || null; this.callbackBody = callbackBody || null; this.returnUrl = returnUrl || null; this.returnBody = returnBody || null; this.asyncOps = asyncOps || null; this.endUser = endUser || null; this.expires = expires || 3600; } scope 限定客户端的权限。如果 scope 是 bucket,则客户端只能新增文件到指定的 bucket,不能修改文件。如果 scope 为 bucket:key,则客户端可以修改指定的文件。注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误 callbackUrl 设定业务服务器的回调地址,这样业务服务器才能感知到上传行为的发生。 callbackBody 设定业务服务器的回调信息。文件上传成功后,七牛向业务服务器的callbackUrl发送的POST请求携带的数据。支持 魔法变量 和 自定义变量。 returnUrl 设置用于浏览器端文件上传成功后,浏览器执行303跳转的URL,一般为 HTML Form 上传时使用。文件上传成功后浏览器会自动跳转到 returnUrl?upload_ret=returnBody。 returnBody 可调整返回给客户端的数据包,支持 魔法变量 和 自定义变量。returnBody 只在没有 callbackUrl 时有效(否则直接返回 callbackUrl 返回的结果)。不同情形下默认返回的 returnBody 并不相同。在一般情况下返回的是文件内容的 hash,也就是下载该文件时的 etag;但指定 returnUrl 时默认的 returnBody 会带上更多的信息。 asyncOps 可指定上传完成后,需要自动执行哪些数据处理。这是因为有些数据处理操作(比如音视频转码)比较慢,如果不进行预转可能第一次访问的时候效果不理想,预转可以很大程度改善这一点。 expires指定uptoken的过期时间,默认3600s 关于上传策略更完整的说明,请参考 上传凭证。

生成上传凭证 服务端生成 上传凭证 代码如下:

function uptoken(bucketname) { var putPolicy = new qiniu.rs.PutPolicy(bucketname); //putPolicy.callbackUrl = callbackUrl; //putPolicy.callbackBody = callbackBody; //putPolicy.returnUrl = returnUrl; //putPolicy.returnBody = returnBody; //putPolicy.asyncOps = asyncOps; //putPolicy.expires = expires;

return putPolicy.token(); }

PutExtra

PutExtra是上传时的可选信息,默认为null

function PutExtra(params, mimeType, crc32, checkCrc) { this.paras = params || {}; this.mimeType = mimeType || null; this.crc32 = crc32 || null; this.checkCrc = checkCrc || 0; } params 是一个字典。自定义变量,key必须以 x: 开头命名,不限个数。可以在 uploadToken 的 callbackBody 选项中求值。 mime_type 表示数据的MimeType,当不指定时七牛服务器会自动检测。 crc32 待检查的crc32值 check_crc 可选值为0, 1, 2。 check_crc == 0: 表示不进行 crc32 校验。 check_crc == 1: 上传二进制数据时等同于 check_crc=2;上传本地文件时会自动计算 crc32 值。 check_crc == 2: 表示进行 crc32 校验,且 crc32 值就是上面的 crc32 变量 上传文件 上传文件到七牛(通常是客户端完成,但也可以发生在服务端):

直接上传二进制流:

function uploadBuf(body, key, uptoken) { var extra = new qiniu.io.PutExtra(); //extra.params = params; //extra.mimeType = mimeType; //extra.crc32 = crc32; //extra.checkCrc = checkCrc;

qiniu.io.put(uptoken, key, body, extra, function(err, ret) { if (!err) { // 上传成功, 处理返回值 console.log(ret.key, ret.hash); // ret.key & ret.hash } else { // 上传失败, 处理返回代码 console.log(err) // http://developer.qiniu.com/docs/v6/api/reference/codes.html } }); } 上传本地文件:

function uploadFile(localFile, key, uptoken) { var extra = new qiniu.io.PutExtra(); //extra.params = params; //extra.mimeType = mimeType; //extra.crc32 = crc32; //extra.checkCrc = checkCrc;

qiniu.io.putFile(uptoken, key, localFile, extra, function(err, ret) { if(!err) { // 上传成功, 处理返回值 console.log(ret.key, ret.hash); // ret.key & ret.hash } else { // 上传失败, 处理返回代码 console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } }); }

下载文件

下载公有文件 每个 bucket 都会绑定一个或多个域名(domain)。如果这个 bucket 是公开的,那么该 bucket 中的所有文件可以通过一个公开的下载 url 可以访问到:

http:/// 其中是bucket所对应的域名。七牛云存储为每一个bucket提供一个默认域名。默认域名可以到七牛云存储开发者平台中,空间设置的域名设置一节查询。用户也可以将自有的域名绑定到bucket上,通过自有域名访问七牛云存储。

假设某个 bucket 既绑定了七牛的二级域名,如 hello.qiniudn.com,也绑定了自定义域名(需要备案),如www.hello.com。而该 bucket 中 有一个key 为 a/b/c.htm 的文件可以通过http://hello.qiniudn.com/a/b/c.htm或http://www.hello.com/a/b/c.htm中任意一个 url 进行访问。

注意: key必须采用utf8编码,如使用非utf8编码访问七牛云存储将反馈错误

下载私有文件 如果某个 bucket 是私有的,那么这个 bucket 中的所有文件只能通过一个的临时有效的 downloadUrl 访问:

http:///?e=&token= 其中 dntoken 是由业务服务器签发的一个临时下载授权凭证,deadline 是 dntoken 的有效期。dntoken不需要单独生成,SDK 提供了生成完整 downloadUrl 的方法(包含了 dntoken),示例代码如下:

function downloadUrl(domain, key) { var baseUrl = qiniu.rs.makeBaseUrl(domain, key); var policy = new qiniu.rs.GetPolicy(); return policy.makeRequest(baseUrl); } 生成 downloadUrl 后,服务端下发 downloadUrl 给客户端。客户端收到 downloadUrl 后,和公有资源类似,直接用任意的 HTTP 客户端就可以下载该资源了。唯一需要注意的是,在 downloadUrl 失效却还没有完成下载时,需要重新向服务器申请授权。

无论公有资源还是私有资源,下载过程中客户端并不需要七牛 SDK 参与其中。

断点续下载 无论是公有资源还是私有资源,获得的下载 url 支持标准的 HTTP 断点续传协议。考虑到多数语言都有相应的断点续下载支持的成熟方法,七牛 Nodejs-SDK 并不提供断点续下载相关代码。

资源操作

资源操作限在服务端操作,先进行初始化

qiniu.conf.ACCESS_KEY = ''; qiniu.conf.SECRET_KEY = '';

获取文件信息

var client = new qiniu.rs.Client(); client.stat(bucketName, key, function(err, ret) { if (!err) { // ok // ret has keys (hash, fsize, putTime, mimeType) } else { console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } });

删除文件

var client = new qiniu.rs.Client(); client.remove(bucketName, key, function(err, ret) { if (!err) { // ok } else { console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } })

复制/移动文件

var client = new qiniu.rs.Client(); client.copy(bucketSrc, keySrc, bucketDest, keyDest, function(err, ret) { if (!err) { // ok } else { console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } }); var client = new qiniu.rs.Client(); client.move(bucketSrc, keySrc, bucketDest, keyDest, function(err, ret) { if (!err) { // ok } else { console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } });

批量操作

当您需要一次性进行多个操作时, 可以使用批量操作。 批量操作的几个函数中,当返回值err为null的时候,有两种情况:

批量操作的所有操作都成功 批量操作仅仅部分成功 因此在返回成功的时候还需要检查各个子项目的返回值(详细见各个示例)。 注意:批量操作不是对单个文件操作的包装,而是有独立的接口。

批量获取文件信息

var path0 = new qiniu.rs.EntryPath(bucketName, key0); var path1 = new qiniu.rs.EntryPath(bucketName, key1); var path2 = new qiniu.rs.EntryPath(bucketName, key2); var client = new qiniu.rs.Client();

client.batchStat([path0, path1, path2], function(err, ret) { if (!err) { for (i in ret) { if (ret[i].code === 200) { //ok, ret[i].data has keys (hash, fsize, putTime, mimeType) } else { // parse error code console.log(ret[i].code, ret[i].data); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } } } else { console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } }); 批量复制文件

var pathSrc0 = new qiniu.rs.EntryPath(bucketName, key0); var pathDest0 = new qiniu.rs.EntryPath(bucketName, key1); var pathSrc1 = new qiniu.rs.EntryPath(bucketName, key2); var pathDest1 = new qiniu.rs.EntryPath(bucketName, key3);

var pair0 = new qiniu.rs.EntryPathPair(pathSrc0, pathDest0); var pair1 = new qiniu.rs.EntryPathPair(pathSrc1, pathDest1);

var client = new qiniu.rs.Client();

client.batchCopy([pair0, pair1], function(err, ret) { if (!err) { for (i in ret) { if (ret[i].code !== 200) { // parse error code console.log(ret[i].code, ret[i].data); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } }

} else { console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } }); 批量移动文件

var pathSrc0 = new qiniu.rs.EntryPath(bucketName, key0); var pathDest0 = new qiniu.rs.EntryPath(bucketName, key1); var pathSrc1 = new qiniu.rs.EntryPath(bucketName, key2); var pathDest1 = new qiniu.rs.EntryPath(bucketName, key3);

var pair0 = new qiniu.rs.EntryPathPair(pathSrc0, pathDest0); var pair1 = new qiniu.rs.EntryPathPair(pathSrc1, pathDest1);

var client = new qiniu.rs.Client();

client.batchMove([pair0, pair1], function(err, ret) { if (!err) { for (i in ret) { if (ret[i] !== 200) { // parse error code console.log(ret[i].code, ret[i].data); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } } } else { console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } }); 批量删除文件

var path0 = new qiniu.rs.EntryPath(bucketName, key0); var path1 = new qiniu.rs.EntryPath(bucketName, key1); var path2 = new qiniu.rs.EntryPath(bucketName, key2);

var client = new qiniu.rs.Client();

client.batchDelete([path0, path1, path2], function(err, ret) { if (!err) { for (i in ret) { if (ret[i].code !== 200) { // parse error code console.log(ret[i].code, ret[i].data); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } } } else { console.log(err); // http://developer.qiniu.com/docs/v6/api/reference/codes.html } });

高级管理操作

列出文件

请求某个存储空间(bucket)下的文件列表,如果有前缀,可以按前缀(prefix)进行过滤;第一次调用时置marker为null,之后的调用填上服务器返回的marker(如果有),则列出刚刚为列完的文件

qiniu.conf.ACCESS_KEY = ''; qiniu.conf.SECRET_KEY = '';

qiniu.rsf.listPrefix(bucketname, prefix, marker, limit, function(err, ret) { if (!err) { // process ret.marker & ret.items } else { console.log(err) // http://developer.qiniu.com/docs/v6/api/reference/rs/list.html } });

云处理

查看图像信息

// 生成访问图片的url var url = qiniu.rs.makeBaseUrl(bucketDomain, key); // bucketDomain为空间域名

// 生成fop_url var ii = new qiniu.fop.ImageInfo(); url = ii.makeRequest(url);

// 签名,生成private_url。如果是公有bucket则此步可以省略 // 服务端操作使用,或者发送给客户端 var policy = new qiniu.rs.GetPolicy(); url = policy.makeRequest(url);

console.log('在浏览器输入: ' + url); 查看图像Exif

// 生成访问图片的url var url = qiniu.rs.makeBaseUrl(bucketDomain, key); // bucketDomain为空间域名

// 生成fop_url var exif = new qiniu.fop.Exif(); url = exif.makeRequest(url);

// 签名,生成private_url。如果是公有bucket则此步可以省略 // 服务端操作使用,或者发送给客户端 var policy = new qiniu.rs.GetPolicy(); url = policy.makeRequest(url);

console.log('在浏览器输入: ' + url); 生成缩略图

// 生成访问图片的url var url = qiniu.rs.makeBaseUrl(bucketDomain, key);

// 生成fop_url var iv = new qiniu.fop.ImageView(); iv.width = 100; url = iv.makeRequest(url);

// 签名,生成private_url。如果是公有bucket则此步可以省略 // 服务端操作使用,或者发送给客户端 var policy = new qiniu.rs.GetPolicy(); url = policy.makeRequest(url);

console.log('在浏览器输入: ' + url);

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /