@winman-f2e/nos-js-web
v1.0.1
Published
浏览器上使用的nos直传
Downloads
179
Keywords
Readme
@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步,第二步是可以在任意业务场景中使用的。
常见问题
写在前面的几个概念
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|错误说明|code|message| |---|---|---|---| |GET_TOKEN_FAIL|获取token失败|100|get NOS token fail| |DEFAULT_UPLOAD_FAIL|defaultUploader上传失败|1000|| |BLOCK_RETRIES_EXCEEDED|blockUploader重试过多,上传失败|2000|upload error: retries have exceeded the limit.| |BLOCK_FETCH_OFFSET_FAIL|blockUploader获取上次上传进度失败|2001|| |CONCURRENT_GET_UPLOAD_ID_FAIL|concurrentUploader获取uploadId失败|3000|| |CONCURRENT_GET_BLOCK_MD5_FAIL|concurrentUploader获取分片md5失败|3001|| |CONCURRENT_GET_COMPLETE_ALL_BLOCKS_FAIL|concurrentUploader分片完成后,合并分片失败|3002|| |CONCURRENT_RETRIES_EXCEEDED|concurrentUploader重试次数过多|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
- 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 包中导出