1.0.1 • Published 4 months ago

@winman-f2e/nos-js-web v1.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
4 months ago

@winman-f2e/nos-js-web

浏览器上使用的nos直传

安装

npm i @winman-f2e/nos-js-web

快速开始

第一步 创建一个通用上传配置

比如shared/nos-uploader

import {
  NOSWebClass,
  NOSDefaultUploader
} from '@winman-f2e/nos-js-web';

const NOSUploader = new NOSWebClass(NOSDefaultUploader);
// NOSDefaultUploader 是使用的上传方式
// 有以下3种方式可供选择
// - NOSDefaultUploader - 默认上传方式,单请求上传整个文件
// - NOSBlockUploader - NOS分块直传,串行上传
// - NOSConcurrentUploader - 并行分块直传

NOSUploader.useGetToken((uploader) => {
  const file = uploader._originFile;
  return fetch(
    // 这是业务接口的内容,可以查看nos直传文档(https://sf.163.com/help/documents/67031136644288512)了解接口内容
    '/genUploadToken'
  ).then(({ response }) => {
      const data = await response.json();
      return {
        objectKey: data.objectName, // NOS 对象名
        bucketName: data.bucketName, // NOS 桶名
        token: data.uploadToken // NOS 直传凭证: https://sf.163.com/help/documents/67031136644288512
      }
    })
})

export NOSUploader;

第二步 开始上传

比如在react中使用

import React, {
  useCallback
} from 'react'
import { NOSUploader } from './shared/nos-uploader';

const Uploader = () => {
  const uploadFile = useCallback((file) => {
    const task = NOSUploader.createUploadTask(file);
    // 监听上传进度
    task.addListener('progress', () => {
      // 上传中信息,详细内容可查看【#task.uploadInfo 上传中进度信息】
      /**
      {
        percent: number,
        timestamp: number,
        sent?: number,
        total?: number
      }
      **/
      task.uploadInfo
    );
    // 监听上传完成
    task.addListener('complete', () => {
      task.uploadedInfo
    });
    // 监听上传错误
    task.addListener('error', () => {});

    // 开始上传
    task.upload();
  }, []);
  return (
    <div>
      <button
        type="file"
        onClick={(event) => {
          uploadFile(event.target.files[0])
        }}
      ></button>
    </div>
  )
}

总共2步,第二步是可以在任意业务场景中使用的。

常见问题

FAQ

写在前面的几个概念

NOSClass 平台适配类

  • NOSClass
  • NOSWebClass

Uploader 上传行为

  • NOSDefaultUploader - 默认上传方式,单请求上传整个文件
  • NOSBlockUploader - NOS分块直传,串行上传
  • NOSConcurrentUploader - 并行分块直传

upload 上传实例

const upload = new NOSWebClass(
  NOSConcurrentUploader // NOSDefaultUploader或NOSBlockUploader或NOSConcurrentUploader
)

这句表示,用浏览器支持的方式构建一个并行分块上传

task 一个具体的文件上传任务

const task = upload.createUploadTask(file)

task的属性

task.uploadInfo 上传中进度信息
export interface UploadInfo {
  /**
   * 上传进度 0-1
   */
  percent: number,
  /**
   * 上次更新的时间戳
   */
  timestamp: number,
  /**
   * 已发送的文件大小
   */
  sent?: number,
  /**
   * 文件总大小
   */
  total?: number
}
task.uploadedInfo 上传完成后的nos数据
/**
 * UploadedInfo 上传完成后的nos数据
 */
export interface UploadedInfo {
  objectKey: string,
  bucketName: string
}

task的函数

task.upload()

开始上传

task.pause()

暂停上传,暂停后调用task.upload会继续上传

task.abort()

取消上传,进度清零

task.destroy()

销毁,会取消上传,并移除所有事件

task.addListener|task.removeListener

添加和移除事件,可以查看task的事件

task的事件

可以通过

const callback = () => {};
// 添加监听事件
task.addListener('事件名字', callback);
// 移除监听事件
task.removeListener('事件名字', callback);

// 移除所有该事件名上的监听
task.removeListener('事件名字');
// 移除该函数绑定的所有事件
task.removeListener(callback);
progress

上传进度事件

complete

上传完成事件

error

上传错误事件

import {
  ERROR_CODE_MAP
} from '@winman-f2e/nos-js-web';

task.addListener('error', (event) => {
  const error = event.data;
  if (error.code === ERROR_CODE_MAP.CONCURRENT_GET_BLOCK_MD5_FAIL.code) {
    // concurrentUploader获取分片md5失败
  }
});

ERROR_CODE_MAP说明:

key错误说明codemessage
GET_TOKEN_FAIL获取token失败100get NOS token fail
DEFAULT_UPLOAD_FAILdefaultUploader上传失败1000
BLOCK_RETRIES_EXCEEDEDblockUploader重试过多,上传失败2000upload error: retries have exceeded the limit.
BLOCK_FETCH_OFFSET_FAILblockUploader获取上次上传进度失败2001
CONCURRENT_GET_UPLOAD_ID_FAILconcurrentUploader获取uploadId失败3000
CONCURRENT_GET_BLOCK_MD5_FAILconcurrentUploader获取分片md5失败3001
CONCURRENT_GET_COMPLETE_ALL_BLOCKS_FAILconcurrentUploader分片完成后,合并分片失败3002
CONCURRENT_RETRIES_EXCEEDEDconcurrentUploader重试次数过多3003

更多使用方法

定义自己的业务 NOS token 获取方式

1. 实例化后注入

import {
  NOSWebClass,
  NOSDefaultUploader
} from '@winman-f2e/nos-js-web';

const upload = new NOSWebClass(NOSDefaultUploader);

upload.useGetToken((uploader) => {
  const file = uploader._originFile;
  return fetch(
    '/genUploadToken'
  ).then(({ response }) => {
      const data = await response.json();
      return {
        objectKey: data.objectName, // NOS 对象名
        bucketName: data.bucketName, // NOS 桶名
        token: data.uploadToken // NOS 直传凭证: https://sf.163.com/help/documents/67031136644288512
      }
    })
})

2. 创建新类

class CustomNOSClass extends NOSWebClass {
  getNOSToken: (uploader) => Promise<{ objectKey: string, bucketName: string, token: string}>
}

当然也可以在实例化后在此之前动态修改

const customNOS = new CustomNOSClass(NOSDefaultUploader);

customNOS.useGetToken(() => {
  // ....
})

使用非nos.netease.com上传,如建德的NOS分区

如果我们申请的NOS桶分区不属于 nos.netease.com。如果属于建德的,那我们可以修改如下:

import {
  APIS
} from '@winman-f2e/nos-js';
import {
  NOSWebClass,
  NOSDefaultUploader
} from '@winman-f2e/nos-js-web';

const upload = new NOSWebClass(NOSDefaultUploader);

upload.updateAPI(APIS.jd);

当然也可以根据实际的需求进行变更。变更方法如下:

upload.updateAPI({
  NOS_UPLOAD: {
    url: 'https://{bucketName}.nos-jd.163yun.com',
    method: 'POST'
  },

  NOS_GET_OBJECT: {
    url: 'https://{bucketName}.nos-jd.163yun.com/{objectKey}',
  },

  NOS_BLOCK_UPLOAD: {
    url: 'https://{bucketName}.nos-jd.163yun.com/{objectKey}',
    method: 'POST'
  },

  // 获取上传进度
  FETCH_BLOCK_UPLOAD_CONTEXT: {
    url: 'https://{bucketName}.nos-jd.163yun.com{objectKey}',
    method: 'GET'
  },

  NOS_CONCURRENT_UPLOAD: {
    url: 'https://{bucketName}.nos-jd.163yun.com/{objectKey}'
  }
})

其中 {bucketName}{objectKey}useGetToken 返回数据的占位符,会自动替换

配置并行上传的分块大小

import {
  NOSWebClass,
  NOSConcurrentUploader
} from '@winman-f2e/nos-js-web';

class MyNOSConcurrentUploader extends NOSConcurrentUploader {
  blockSize = 1024 * 1024 * 10, // 默认:10MB
  shouldUpdateProgressFromBlockUploading = true // 设置是否在每个分块上传一部分也更新整体进度,关闭可以方式暂停的进度回退。但是需要配合设置一个blockSize,才能获得一个比较好的进度体验
}
const upload = new NOSWebClass(MyNOSConcurrentUploader);

自定义上传逻辑

比如我们需要再上传完成后,额外发送一个请求,校验文件信息,才能确认上传完成

import {
  NOSWebClass,
  NOSConcurrentUploader
 } from '@winman-f2e/nos-js-web';


export class CustomUploader extends NOSConcurrentUploader {
  public checkRemote = () => {
    return fetch(
      '/check',
      {
        method: 'GET',
        query: {
          objectName: this.signature?.key
        }
      }
    )
  }

  updateProgress (progressInfo) {
    // 未获取信息前,最大 99%;
    progressInfo.percent = Math.min(0.99, progressInfo.percent);
    super.updateProgress.call(this, progressInfo)
  }

  setComplete () {
    return this.checkRemote()
      .then(
        () => {
          super.setComplete.call(this)
        },
        () => {
          this.setError('文件校验有误')
        })
  }
}

// 使用 new NOSWebClass 进行实例化,即会可以在
const upload = new NOSWebClass(CustomUploader);

API

import {
  NOSClass,
  NOSUploader,
  NOSBlockUploader,
  NOSDefaultUploader,
  NOSConcurrentUploader,

  WebAdapter,
  NOSWebClass,
  NOSWeb,
  BlockNOSWeb,
  ConcurrentNOSWeb
} from '@winman-f2e/nos-js-web';

来自 @winman-f2e/nos-js

参考 @winman-f2e/nos-js API

  • NOSClass
  • NOSUploader
  • NOSBlockUploader
  • NOSDefaultUploader
  • NOSConcurrentUploader

特有API

WebAdapter 和 NOSWebClass

  • WebAdapter 是浏览器端的适配器工具实现的集合
  • NOSWebClass 是 WebAdapter 装配到 NOSClass 后的产物

一般直接使用NOSWebClass即可,如:

const upload = new NOSWebClass(CustomUploader);

即可完成浏览器端自定义上传器。

NOSWeb

export const NOSWeb = new NOSWebClass(NOSDefaultUploader);

使用方法:基础使用例子

BlockNOSWeb

使用方法同NOSWeb

export const BlockNOSWeb = new NOSWebClass(NOSBlockUploader);

ConcurrentNOSWeb

使用方法同NOSWeb

export const ConcurrentNOSWeb = new NOSWebClass(NOSConcurrentUploader);

RichMediaURL 富媒体url处理工具

@winman-f2e/nos-js#richmediaurl-富媒体url处理工具 直接从 @winman-f2e/nos-js 包中导出

1.0.1

4 months ago

1.0.1-beta.0

4 months ago

1.0.0

8 months ago

0.1.6-beta.2

2 years ago

0.1.6-beta.3

2 years ago

0.1.6-beta.0

2 years ago

0.1.6-beta.1

2 years ago

1.0.0-beta.2

1 year ago

1.0.0-beta.3

1 year ago

1.0.0-beta.0

1 year ago

1.0.0-beta.1

1 year ago

0.1.6

2 years ago

0.1.5

2 years ago

0.1.4

2 years ago

0.1.3

2 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago