用户可以通过以下方式向OSS中上传文件:

  • 上传blob数据
  • 断点上传

上传Blob数据

Blob,Binary Large Object的缩写,代表二进制类型的大对象。Blob的概念在一些数据库中有使用到,例如,MYSQL中的BLOB类型就表示二进制数据的容器。

用户也可以通过put接口简单地将Blob中的内容上传到OSS:

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

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

async function putBlob () {
  try {
    let result = await client.put('object-key', new Blob(['content'],{ type: 'text/plain' }));
    console.log(result);
  } catch (e) {
    conosle.log(e);
  }
}
putBlob();

断点上传

在需要上传的文件较大时,可以通过multipartUpload接口进行分片上传。分片上传的好处是将一个大请求分成多个小请求来执行。这样当其中一些分片请求失败后,保留上传进度记录,再次重传时,不需要重新上传整个文件,而只需要上传失败的分片就可以了。一般对于大于100MB的文件,建议采用分片上传的方法,通过断点续传和重试,提高上传成功率。

在使用multipartUpload接口如果遇到ConnectionTimeoutError超时问题,业务方需要自己处理超时逻辑。如何处理超时,可以缩小分片大小、加大超时时间、重试请求,或者业务上捕获ConnectionTimeoutError错误,然后给用户提示。参见网络错误处理

断点上传api的使用方式具体参见MultipartUpload

相关参数:

  • name {String} object 名称
  • file {File|Blob} HTML5 Web File or Blob的数据格式
  • [options] {Object} 额外参数
    • [checkpoint] {Object} 断点记录点,可以进行断点续传, 如果设置这个参数,上传会从断点开始,如果没有设置,就会重新上传.
      • file {File} 用户选取的文件对象,如果浏览器重启后这个需要用户手动触发进行设置
      • name {String} 上传的object key
      • fileSize {Number} 文件大小
      • partSize {Number} 分片大小
      • uploadId {String} 分片上传的ID
      • doneParts {Array} 已完成的分片的数组, 包含的对象结构如下
        • number {Number} 分片的number
        • etag {String} 分片的etag
    • [parallel] {Number} 并发上传的分片个数
    • [partSize] {Number} 分片大小
    • [progress] {Function} functionasyncpromise 形式, 回调函数包含三个参数
      • (percentage {Number} 进度百分比(0-1之间小数)
      • checkpoint {Object} 断点记录点
      • res {Object}) 单次part成功返回的response
    • [meta] {Object} 用户自定义header meta信息, header前缀 x-oss-meta-
    • [mime] {String} 用户自定义 Content-Type header
    • [headers] {Object} http 额外的头字段, 详情请看 RFC 2616
      • 'Cache-Control' 通用消息头被用于在http 请求和响应中通过指定指令来实现缓存机制, e.g.: Cache-Control: public, no-cache
      • 'Content-Disposition' 指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地, e.g.: Content-Disposition: somename
      • 'Content-Encoding' 用于对特定媒体类型的数据进行压缩, e.g.: Content-Encoding: gzip
      • 'Expires' 过期时间, e.g.: Expires: 3600000
    • [callback] {Object} callback回调设置。具体内容参见Callback
      • url {String} 和oss server交互的回调服务器地址。对应于CallBack参数中的callbackUrl。必须有。
      • body {String} 发起回调时请求body的值。jason格式。对应于CallBack参数中的callbackBody。必须有。
      • [host] {String} 发起回调请求时Host头的值。对应于CallBack参数中的callbackHost。
      • [contentType] {String} 发起回调请求的Content-Type。对应于CallBack参数中的callbackBodyType 。
      • [customValue] {Object} 发起回调请求自定义参数。对应于CallBack参数中的callback-var。

范例:

  1. 记录上传进度。再次上传时将之前记录的checkpoint参数传入即可.
  2. 每次进行分片上传建议重新new一个新的OSS实例.
let OSS = require('ali-oss')

let ossConfig = {
  region: '<Your region>',
  accessKeyId: '<Your AccessKeyId>',
  accessKeySecret: '<Your AccessKeySecret>',
  bucket: 'Your bucket name'
}

let client = new OSS(ossConfig);

let tempCheckpoint;

// 定义上传方法
async function multipartUpload () {
  try {
    let result = await client.multipartUpload('object-key', 'local-file', { 
      progress: async function (p, checkpoint) {
        // 记录断点, 如果关闭了浏览器,然后重新启动继续上传的话,是不行的,请参考上边对file对象的描述
        tempCheckpoint = checkpoint;
      }
      meta: { year: 2017, people: 'test' },
      mime: 'image/jpeg'
   })
  } catch(e){
    console.log(e);
  }
}

//开始上传
multipartUpload();

// 暂停分片上传方法
client.cancel();

// 恢复上传
let resumeclient = new OSS(ossConfig);
async function resumeUpload () {
  try {
    let result = await resumeclient.multipartUpload('object-key', 'local-file', {
	progress: async function (p, checkpoint) {
          tempCheckpoint = checkpoint;
        },
        checkpoint: tempCheckpoint
        meta: { year: 2017, people: 'test' },
        mime: 'image/jpeg'
  })
  } catch (e) {
    console.log(e);
  }
}

resumeUpload();

上面的progress参数是一个进度回调函数,用于获取上传进度

const progress = async function progress(p, checkpoint) {
  console.log(p)
};
上面的 meta参数是一个用户自定义的元数据,通过head接口可以获取到object的meta数据,但是这个meta header 需要在控制台跨域设置里边的暴露header中设置好,如图:

请求成功后的返回结果展示:

上面的上传回调通知具体使用可以在options参数中添加 callback,代码如下:

callback: {
  url: 'http://oss-demo.aliyuncs.com:23450',
  host: 'oss-cn-hangzhou.aliyuncs.com',
  /* eslint no-template-curly-in-string: [0] */
  body: 'bucket=${bucket}&object=${object}&var1=${x:var1}',
  contentType: 'application/x-www-form-urlencoded',
  customValue: {
    var1: 'value1',
    var2: 'value2',
  },
},