基于node.js的阿里云对象存储服务OSS

目录

1.环境准备
2.安装SDK
3.初始化client
4.查看Bucket列表
5.查看文件列表
6.文件管理&模拟目录结构
7.文件元信息

Quick Start

阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。本文基于node.js使用阿里云提供的SDK接口将海量数据移入或移出阿里云OSS。

OSS提供多种语言的 API/SDK 包,方便开发人员快速进行二次开发。以下是在Node.js环境中快速使用OSS服务的具体步骤:


环境准备

(1)在使用阿里云 OSS 服务之前,请确保您已经注册了阿里云账号并完成实名认证。使用主账号登录阿里云管理控制台,将鼠标置于页面右上方的账号图标,然后单击accesskeys,创建AccessKeyId和AccessKeySecret。由于云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践。如果部署在服务端可以使用RAM子账号或STS来进行API访问或日常运维管控操作,如果部署在客户端请使用STS方式来进行API访问。

(2)单击对象存储OSS,打开OSS产品详情页面,在OSS产品详情页,单击立即开通,开通服务后,在OSS 产品详情页面单击管理控制台直接进入 OSS 管理控制台界面。

(3)创建存储空间(Bucket)。进入 OSS 管理控制台界面。如果目前 Bucket 列表为空,单击左侧存储空间列表中的新建 Bucket;若已创建过 Bucket,则单击左侧存储空间列表中的新增按钮+,或者单击页面右上方的新建 Bucket 按钮,打开新建 Bucket 对话框(如下图)。接着在此Bucket的文件管理栏目下创建一个文件。

创建Bucket是为了后期使用SDK开发时查看Bucket以及传入文件到此次创建的Bucket中。


安装 SDK

使用Node.js,其中Node.js >= 8.0.0 如果需要在 Node.js < 8 的环境中使用,请使用 ali-oss 4.x版本。
使用npm安装SDK开发包(如下图)。

npm install ali-oss

初始化 Client

  1. region 指申请 OSS 服务时的区域,完整区域列表可在OSS 服务节点查看
  2. accessKeyId 和 accessKeySecret 可在用户信息管理中创建或获取
// app.js
let OSS = require("ali-oss");

let client = new OSS({
  region: "<Your region>",
  accessKeyId: "<Your AccessKeyId>",
  accessKeySecret: "<Your AccessKeySecret>"
});

其中’your region’是指在申请OSS服务时的区域,例如申请的是华东1(杭州),region为oss-cn-hangzhou,完整的区域列表可以在OSS服务节点查看。和即在环境安装中创建的AccessKeyId和AccessKeySecret。


查看 Bucket 列表

在app.js末尾添加如下内容,使用listBuckets接口查看Bucket列表:

// app.js
async function listBuckets() {
  try {
    let result = await client.listBuckets();
    console.log("查看Bucket列表");
    console.log(result);
  } catch (err) {
    console.log(err);
  }
}
listBuckets();

// 控制台打印
// 查看Bucket列表
{ buckets:
   [ { name: 'mvb-demo',
       region: 'oss-cn-shanghai',
       creationDate: '2019-03-16T03:18:40.000Z',
       StorageClass: 'Standard' } ],
  owner: { id: '1310495523924984', displayName: '1310495523924984' },
  isTruncated: false,
  nextMarker: null,
  res:
   { status: 200,
     statusCode: 200,
     statusMessage: 'OK',
     headers:
      { server: 'AliyunOSS',
        date: 'Sat, 16 Mar 2019 03:20:03 GMT',
        'content-type': 'application/xml',
        'content-length': '595',
        connection: 'keep-alive',
        'x-oss-request-id': '5C8C6B638DA7CAFD2BA82A37',
        'x-oss-server-time': '55' },
     size: 595,
     aborted: false,
     rt: 104,
     keepAliveSocket: false,
     data:
      <Buffer 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 46 2d 38 22 3f 3e 0a 3c 4c 69 73 74 41 6c 6c 4d 79 42 ... >,
     requestUrls: [ 'http://oss-cn-shanghai.aliyuncs.com/' ],
     timing: null,
     remoteAddress: '106.14.228.198',
     remotePort: 80,
     socketHandledRequests: 1,
     socketHandledResponses: 1 } }

其中AliyunOSS即之前创建的Bucket。


查看文件列表

修改app.js,使用list接口查看文件列表:

client.useBucket("Your bucket name");
async function list() {
  try {
    let result = await client.list({
      "max-keys": 5
    });
    console.log(result);
  } catch (err) {
    console.log(err);
  }
}
list();

其中’Your bucket name’即之前创建的文件,运行并查看结果node app.js

控制台打印 , 查看文件列表

{ res:
   { status: 200,
     statusCode: 200,
     statusMessage: 'OK',
     headers:
      { server: 'AliyunOSS',
        date: 'Sat, 16 Mar 2019 03:27:06 GMT',
        'content-type': 'application/xml',
        'content-length': '226',
        connection: 'keep-alive',
        'x-oss-request-id': '5C8C6D0AF1C42EA0B7AE2124',
        'x-oss-server-time': '14' },
     size: 226,
     aborted: false,
     rt: 59,
     keepAliveSocket: false,
     data:
      <Buffer 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 46 2d 38 22 3f 3e 0a 3c 4c 69 73 74 42 75 63 6b 65 74 ... >,
     requestUrls:
      [ 'http://mvb-demo.oss-cn-shanghai.aliyuncs.com/?max-keys=5' ],
     timing: null,
     remoteAddress: '106.14.228.182',
     remotePort: 80,
     socketHandledRequests: 1,
     socketHandledResponses: 1 },
  objects: undefined,
  prefixes: null,
  nextMarker: null,
  isTruncated: false }

文件管理&模拟目录结构

每个存储空间(Bucket)可以设置多个不同类型的文件对象,例如图片文件对象,文档文件对象等等,依次在对应的文件对象中存放相应的文件(图片文件中存入图片,文档文件中存入文档),通过list来列举当前Bucket下的所有文件。想获取特定前缀的文件,如开头为"my-"的文件,可用prefix只列出符合特定前缀的图片,以下代码用于列举当前Bucket下前缀为“my-”的所有文件:

let OSS = require('ali-oss');

let client = new OSS({
  region: 'oss-cn-beijing',
  //云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,部署在服务端使用RAM子账号或STS,部署在客户端使用STS。
  accessKeyId: 'LTAImmNI5n0A0b3o',
  accessKeySecret: 'XMcafmH5G5ViSkspkGQE17oTbUZ5iV',
  bucket: 'kekede',
 // endpoint: '<http://oss-cn-beijing.aliyuncs.com>'
});

async function list () {
  {
    let result = await client.list({
      prefix:'my-'
   });
   console.log(result);
  }
}
list();

后台运行结果为:

PS C:\Users\ASUS\Desktop\aliyun> node app.js
{ res:
   { status: 200,
     statusCode: 200,
     statusMessage: 'OK',
     headers:
      { server: 'AliyunOSS',
        date: 'Sat, 16 Mar 2019 07:25:24 GMT',
        'content-type': 'application/xml',
        'content-length': '936',
        connection: 'keep-alive',
        'x-oss-request-id': '5C8CA4E41B658DCC4216F1D8',
        'x-oss-server-time': '17' },
     size: 936,
     aborted: false,
     rt: 124,
     keepAliveSocket: false,
     data:
      <Buffer 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 46 2d 38 22 3f 3e 0a 3c 4c 69 73 74 42 75 63 6b 65 74 ... >,
     requestUrls: [ 'http://kekede.oss-cn-beijing.aliyuncs.com/?prefix=my-' ],
     timing: null,
     remoteAddress: '59.110.185.149',
     remotePort: 80,
     socketHandledRequests: 1,
     socketHandledResponses: 1 },
  objects:
   [ { name: 'my-text/',
       url: 'http://kekede.oss-cn-beijing.aliyuncs.com/my-text/',
       lastModified: '2019-03-16T07:17:19.000Z',
       etag: '"D41D8CD98F00B204E9800998ECF8427E"',
       type: 'Normal',
       size: 0,
       storageClass: 'Standard',
       owner: [Object] },
     { name: 'my-text1/',
       url: 'http://kekede.oss-cn-beijing.aliyuncs.com/my-text1/',
       lastModified: '2019-03-16T07:17:31.000Z',
       etag: '"D41D8CD98F00B204E9800998ECF8427E"',
       type: 'Normal',
       size: 0,
       storageClass: 'Standard',
       owner: [Object] } ],
  prefixes: null,
  nextMarker: null,
  isTruncated: false }

其中my-text与my-text1文件便是带有"my-"前缀的指定文件,可知当我们想搜索带有特定关键字前缀的文件,即可使用。

OSS是基于对象的存储服务,没有目录的概念。存储在一个Bucket中所有文件都是通过文件的key唯一标识,并没有层级的结构。这种结构可以让OSS的存储非常高效,但是用户管理文件时希望能够像传统的文件系统一样把文件分门别类放到 不同的“目录”下面。通过OSS提供的“公共前缀”的功能,也可以很方便地模拟目录结构。

可以通过 Delimiter 和 Prefix 参数的配合实现文件夹功能:
如果把 Prefix 设为某个文件夹名,就可以罗列以此 Prefix 开头的文件,即该文件夹下递归的所有的文件和子文件夹(目录)。文件名在Contents中显示。如果再把 Delimiter 设置为正斜线(/)时,返回值就只罗列该文件夹下的文件和子文件夹(目录),该文件夹下的子文件名(目录)返回在 CommonPrefixes 部分,子文件夹下递归的文件和文件夹不被显示。
现在Bucket中已有如下文件:

my-text/one/one1
my-text/one/one2
my-text1
dididi
review.zip

接下来用调用函数listDir来列举指定目录下的文件和子目录

let OSS = require('ali-oss');

let client = new OSS({
  region: 'oss-cn-beijing',
  accessKeyId: 'LTAImmNI5n0A0b3o',
  accessKeySecret: 'XMcafmH5G5ViSkspkGQE17oTbUZ5iV',
  bucket: 'kekede',
});

async function listDir(dir){
  let result = await client.list({
    prefix: dir,
    delimiter: '/'
  });

  result.prefixes.forEach(function (subDir) {
    console.log('SubDir: %s', subDir);
  });
  result.objects.forEach(function (obj) {
    console.log('Object: %s', obj.name); 
  });
}

listDir('my-text/');

运行结果为

SubDir: my-text/one/
SubDir: my-text/two/
Object: my-text/

输入以下代码

let OSS = require('ali-oss');

let client = new OSS({
  region: 'oss-cn-beijing',
  accessKeyId: 'LTAImmNI5n0A0b3o',
  accessKeySecret: 'XMcafmH5G5ViSkspkGQE17oTbUZ5iV',
  bucket: 'kekede',
});

async function listDir(dir){
  let result = await client.list({
    prefix: dir,
    delimiter: '/'
  });

  result.prefixes.forEach(function (subDir) {
    console.log('SubDir: %s', subDir);
  });
  result.objects.forEach(function (obj) {
    console.log('Object: %s', obj.name); 
  });
}

listDir('my-text/');

运行结果为

SubDir: my-text/
SubDir: my-text1/
(node:12796) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'forEach' of undefined
    at listDir (C:\Users\ASUS\Desktop\aliyun\app.js:21:18)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:12796) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a
promise which was not handled with .catch(). (rejection id: 1)
(node:12796) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

文件元信息

向OSS上传文件时,除了文件内容,还可以指定文件的一些属性信息,称为“元信息”。 这些信息在上传时与文件一起存储,在下载时与文件一起返回。
文件元信息在上传、下载时均附在HTTP Headers中, 且HTTP协议规定不能包含复杂字符。使用put,putStream和multipartUpload时,都可以通过指定meta参数来指定文件的元信息:

let OSS = require('ali-oss')

let client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});

async function put () {
  try {
    let result = await client.put('object-name', 'local-file', {
    meta: {
      year: 2016,
      people: 'mary'
    }
  });
  console.log(result);
  } catch (e) {
    console.log(e);
  }
}

put();

输入以下代码

let OSS = require('ali-oss');

let client = new OSS({
  region: 'oss-cn-beijing',
  accessKeyId: 'LTAImmNI5n0A0b3o',
  accessKeySecret: 'XMcafmH5G5ViSkspkGQE17oTbUZ5iV',
  bucket: 'kekede',
});

async function put () {
  try {
    let result = await client.put('my-text', '1162.jpg', {
    meta: {
      year: 2016,
      people: 'mary'
    }
  });
  console.log(result);
  } catch (e) {
    console.log(e);
  }
}

put();

运行结果如下

{ name: 'my-text',
  url: 'http://kekede.oss-cn-beijing.aliyuncs.com/my-text',
  res:
   { status: 200,
     statusCode: 200,
     statusMessage: 'OK',
     headers:
      { server: 'AliyunOSS',
        date: 'Sat, 16 Mar 2019 16:36:17 GMT',
        'content-length': '0',
        connection: 'keep-alive',
        'x-oss-request-id': '5C8D260131333D99F43812DC',
        etag: '"AFE392E3D901E3C33F1539DD3DA1276F"',
        'x-oss-hash-crc64ecma': '6266394416455372926',
        'content-md5': 'r+OS49kB48M/FTndPaEnbw==',
        'x-oss-server-time': '26' },
     size: 0,
     aborted: false,
     rt: 687,
     keepAliveSocket: false,
     data: <Buffer >,
     requestUrls: [ 'http://kekede.oss-cn-beijing.aliyuncs.com/my-text' ],
     timing: null,
     remoteAddress: '59.110.185.149',
     remotePort: 80,
     socketHandledRequests: 1,
     socketHandledResponses: 1 } }

通过putMeta接口来更新文件元信息:

let OSS = require('ali-oss')

let client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});

async function putMeta () {
  try {
    let result = await client.putMeta('object-name', {
    meta: {
      year: 2015,
      people: 'mary'
    }
  });
  console.log(result);
  } catch (e) {
    console.log(e);
  }
}

putMeta();

输入以下代码

let OSS = require('ali-oss');

let client = new OSS({
  region: 'oss-cn-beijing',
  accessKeyId: 'LTAImmNI5n0A0b3o',
  accessKeySecret: 'XMcafmH5G5ViSkspkGQE17oTbUZ5iV',
  bucket: 'kekede',
});

async function putMeta () {
  try {
    let result = await client.putMeta('my-text', {
    meta: {
      year: 2015,
      people: 'mary'
    }
  });
  console.log(result);
  } catch (e) {
    console.log(e);
  }
}

putMeta();

运行结果如下

{ name: 'my-text',
  url: 'http://kekede.oss-cn-beijing.aliyuncs.com/my-text',
  res:
   { status: 200,
     statusCode: 200,
     statusMessage: 'OK',
     headers:
      { server: 'AliyunOSS',
        date: 'Sat, 16 Mar 2019 16:36:17 GMT',
        'content-length': '0',
        connection: 'keep-alive',
        'x-oss-request-id': '5C8D260131333D99F43812DC',
        etag: '"AFE392E3D901E3C33F1539DD3DA1276F"',
        'x-oss-hash-crc64ecma': '6266394416455372926',
        'content-md5': 'r+OS49kB48M/FTndPaEnbw==',
        'x-oss-server-time': '26' },
     size: 0,
     aborted: false,
     rt: 687,
     keepAliveSocket: false,
     data: <Buffer >,
     requestUrls: [ 'http://kekede.oss-cn-beijing.aliyuncs.com/my-text' ],
     timing: null,
     remoteAddress: '59.110.185.149',
     remotePort: 80,
     socketHandledRequests: 1,
     socketHandledResponses: 1 } }
PS C:\Users\ASUS\Desktop\aliyun> node app.js
{ data:
   { etag: '"AFE392E3D901E3C33F1539DD3DA1276F"',
     lastModified: '2019-03-16T16:37:59.000Z' },
  res:
   { status: 200,
     statusCode: 200,
     statusMessage: 'OK',
     headers:
      { server: 'AliyunOSS',
        date: 'Sat, 16 Mar 2019 16:37:59 GMT',
        'content-type': 'application/xml',
        'content-length': '184',
        connection: 'keep-alive',
        'x-oss-request-id': '5C8D26671B658DD589677FDC',
        etag: '"AFE392E3D901E3C33F1539DD3DA1276F"',
        'x-oss-server-time': '35' },
     size: 184,
     aborted: false,
     rt: 238,
     keepAliveSocket: false,
     data:
      <Buffer 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d 22 55 54 46 2d 38 22 3f 3e 0a 3c 43 6f 70 79 4f 62 6a 65 63 74 ... >,
     requestUrls: [ 'http://kekede.oss-cn-beijing.aliyuncs.com/my-text' ],
     timing: null,
     remoteAddress: '59.110.185.149',
     remotePort: 80,
     socketHandledRequests: 1,
     socketHandledResponses: 1 } }

拷贝文件:

使用copy拷贝文件,拷贝分两种情况:
同一个Bucket
同一个region下的两个不同Bucket,此时源Object名字应为’/bucket/object’的形式
另外,拷贝时对文件元信息的处理有两种选择:
如果没有指定meta参数,则与源文件相同,即拷贝源文件的元信息。
如果指定了meta参数,则使用新的元信息覆盖源文件的信息。

let OSS = require('ali-oss')

let client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});

async function copy () {
  try {
     // 两个Bucket之间拷贝
    let result = await client.copy('to', '/from-bucket/from');
    console.log(result);

    // 拷贝元信息
    let result = await client.copy('to', 'from');
    console.log(result);

    // 覆盖元信息
    let result = await client.copy('to', 'from', {
      meta: {
        year: 2015,
        people: 'mary'
      }
    });
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

输入以下代码

 let OSS = require('ali-oss');

let client = new OSS({
  region: 'oss-cn-beijing',
  accessKeyId: 'LTAImmNI5n0A0b3o',
  accessKeySecret: 'XMcafmH5G5ViSkspkGQE17oTbUZ5iV',
  bucket: 'kekede',
});

async function copy () {
  try {
     // 两个Bucket之间拷贝
    let result = await client.copy('my-text1', '/jiayou1111/jiayoou');
    console.log(result);

    // 拷贝元信息
    let result = await client.copy('my-text1', 'dididi');
    console.log(result);

    // 覆盖元信息
    let result = await client.copy('my-text1', 'dididi', {
      meta: {
        year: 2015,
        people: 'mary'
      }
    });
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

再观看控制台,操作完成。

通过delete来删除某个文件:

let OSS = require('ali-oss')

let client = new OSS({
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
});

async function delete () {
  try {
    let result = yield client.delete('object-name');
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

delete();

输入代码:

let OSS = require('ali-oss');

let client = new OSS({
  region: 'oss-cn-beijing',
  accessKeyId: 'LTAImmNI5n0A0b3o',
  accessKeySecret: 'XMcafmH5G5ViSkspkGQE17oTbUZ5iV',
  bucket: 'kekede',
});


async function remove () {
  try {
    let result = yield client.delete('dididi');
    console.log(result);
  } catch (e) {
    console.log(e);
  }
}

remove();

结果如下图

{ res:
   { status: 204,
     statusCode: 204,
     statusMessage: 'No Content',
     headers:
      { server: 'AliyunOSS',
        date: 'Sat, 16 Mar 2019 17:20:56 GMT',
        'content-length': '0',
        connection: 'keep-alive',
        'x-oss-request-id': '5C8D3078591574B0552D183C',
        'x-oss-server-time': '20' },
     size: 0,
     aborted: false,
     rt: 196,
     keepAliveSocket: false,
     data: <Buffer >,
     requestUrls: [ 'http://kekede.oss-cn-beijing.aliyuncs.com/dididi' ],
     timing: null,
     remoteAddress: '59.110.185.149',
     remotePort: 80,
     socketHandledRequests: 1,
     socketHandledResponses: 1 } }

因上诉delete报错,所以改用remove,再去操作台观看dididi文件已经被删除,操作完成。

还有众多其他功能需阅读阿里云对象存储OSS开发指南:
阿里云对象存储OSS开发指南
作者:木子可可

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值