UNPKG

object-storage-js

Version:

Object storage SDK for browser — supports server upload, MinIO, OBS, OSS, AWS S3, Qiniu Kodo, and Baidu BOS

280 lines (224 loc) 10.5 kB
# object-storage-js 面向浏览器端上传场景的对象存储适配层。它把服务端上传、主流云厂商 SDK 上传和 S3 协议上传统一到同一套初始化、上传、进度和取消接口中,业务代码只需要切换 `type` 和配置即可。 ## 能力概览 - **统一接口**:所有 Provider 通过 `new ObjectStorage(config).upload(params)` 调用。 - **按需引入 SDK**:不内置云厂商 SDK,由业务方通过 `sdkObject` 传入,避免增加基础包体积。 - **上传进度**:统一输出 `{ loaded, total, percent }`。 - **取消上传**:通过 `onCancel` 暴露取消句柄;支持能力取决于底层 SDK 或 XHR。 - **大文件处理**:normal、OSS、OBS、S3/MinIO、七牛云、百度 BOS 等场景按各自 SDK 能力支持分片或并发参数。 - **扩展友好**:内部采用 Adapter 结构,新增 Provider 只需要增加对应上传实现和配置类型。 ## 支持的 Provider | Type | Provider | SDK / 上传方式 | 说明 | | -------- | --------- | ------------------ | ----------------------------- | | `normal` | 业务服务端 | XHR + FormData | 适合上传到自有后端,再由后端落对象存储。 | | `oss` | 阿里云 OSS | `ali-oss` | 支持 AK/SK、STS、multipartUpload。 | | `obs` | 华为云 OBS | OBS Browser SDK | 小文件走预签名 PUT,大文件走 SDK 分片上传。 | | `minio` | MinIO | AWS SDK v2 S3 | S3 兼容协议,默认开启 path style。 | | `aws` | AWS S3 | AWS SDK v2 S3 | 兼容 AWS SDK v2 的 S3 上传能力。 | | `qiniu` | 七牛云 Kodo | 七牛云 JS SDK | 使用业务服务端签发的 uploadToken 上传。 | | `bos` | 百度智能云 BOS | 百度 BOS Browser SDK | 支持 AK/SK、服务端签名和分块上传。 | ## 安装 ```bash pnpm add object-storage-js ``` ## 快速开始 ```ts import ObjectStorage, { ObjectStorageType } from 'object-storage-js'; const storage = new ObjectStorage({ type: ObjectStorageType.OSS, sdkObject: OSS, accessKey: 'your-access-key', secretKey: 'your-secret-key', securityToken: 'optional-sts-token', bucketName: 'example-bucket', endPoint: 'https://oss-cn-hangzhou.aliyuncs.com', }); await storage.upload({ file, fileName: `uploads/${file.name}`, maxSize: 100 * 1024 * 1024, partSize: 5 * 1024 * 1024, queueLength: 3, onUploadProgress(progress) { console.log(progress.percent); }, onCancel(handle) { // handle.cancel(); }, }); ``` ## UMD 用法 适合直接在浏览器中通过 `<script>` 标签引入。UMD 构建会暴露全局变量 `ObjectStorage`,其中包含默认导出的构造函数、命名导出的 `ObjectStorage` 和 `ObjectStorageType`。 ```html <input id="file" type="file" /> <script src="https://unpkg.com/object-storage-js/dist/index.umd.js"></script> <script> const { ObjectStorage: StorageClient, ObjectStorageType } = window.ObjectStorage; document.querySelector('#file').addEventListener('change', async (event) => { const file = event.target.files[0]; if (!file) return; const storage = new StorageClient({ type: ObjectStorageType.NORMAL, }); await storage.upload({ file, fileName: file.name, uploadUrl: '/api/files/upload', mergeUrl: '/api/files/merge', maxSize: 100 * 1024 * 1024, onUploadProgress(progress) { console.log(`upload progress: ${progress.percent}%`); }, }); }); </script> ``` ## API ### `new ObjectStorage(config)` 公共配置字段: | 字段 | 类型 | 说明 | | ---------------- | ------------------------- | ----------------------------- | | `type` | `ObjectStorageType` | Provider 类型。 | | `sdkObject` | `unknown` | 云厂商 SDK 构造函数或模块;`normal` 不需要。 | | `sdkOtherParams` | `Record<string, unknown>` | 透传给 SDK 构造函数的额外参数。 | Provider 配置字段: | Provider | 必填字段 | 可选字段 | | --------------- | ------------------------------------- | --------------------------------------------------------------------------------- | | `normal` ||| | `oss` | `sdkObject`, `bucketName`, `endPoint` | `accessKey`, `secretKey`, `securityToken`, `region`, `sdkOtherParams` | | `obs` | `sdkObject`, `bucketName`, `endPoint` | `accessKey`, `secretKey`, `securityToken`, `sdkOtherParams` | | `minio` / `aws` | `sdkObject`, `bucketName` | `accessKey`, `secretKey`, `securityToken`, `endPoint`, `region`, `sdkOtherParams` | | `qiniu` | `sdkObject` | `uploadToken`, `sdkOtherParams` | | `bos` | `sdkObject`, `bucketName`, `endPoint` | `accessKey`, `secretKey`, `signatureUrl`, `sdkOtherParams` | ### `upload(params)` | 字段 | 类型 | 说明 | | ------------------ | ------------------------- | ----------------------------------- | | `file` | `File` | 要上传的文件。 | | `fileName` | `string` | 目标对象 key;不传时使用 `file.name`。 | | `maxSize` | `number` | 超过该大小后启用分片/大文件策略,具体行为由 Provider 决定。 | | `partSize` | `number` | 分片大小,单位字节。 | | `queueLength` | `number` | 分片上传并发数。 | | `uploadUrl` | `string` | `normal` 上传接口地址。 | | `mergeUrl` | `string` | `normal` 分片合并接口地址。 | | `uploadToken` | `string` | 上传凭证,例如七牛云 token;会覆盖初始化配置里的 token。 | | `contentType` | `string` | 显式指定内容类型。 | | `sdkUploadParams` | `Record<string, unknown>` | 透传给厂商上传方法的额外参数。 | | `onUploadProgress` | `(progress) => void` | 上传进度回调。 | | `onCancel` | `(handle) => void` | 上传可取消时回调取消句柄。 | ## Provider 示例 ### normal:上传到业务服务端 ```ts const storage = new ObjectStorage({ type: ObjectStorageType.NORMAL, }); await storage.upload({ file, uploadUrl: '/api/files/upload', mergeUrl: '/api/files/merge', maxSize: 100 * 1024 * 1024, }); ``` `normal` 分片上传会向 `uploadUrl` 提交 `file`、`uploadId`、`chunk`、`chunks`、`fileName`,最后请求 `mergeUrl?uploadId=xxx&fileName=xxx`。 ### 阿里云 OSS ```ts import OSS from 'ali-oss'; import ObjectStorage, { ObjectStorageType } from 'object-storage-js'; const storage = new ObjectStorage({ type: ObjectStorageType.OSS, sdkObject: OSS, bucketName: 'example-bucket', endPoint: 'https://oss-cn-hangzhou.aliyuncs.com', region: 'oss-cn-hangzhou', accessKey: 'your-sts-access-key-id', secretKey: 'your-sts-access-key-secret', securityToken: 'your-sts-token', }); await storage.upload({ file, fileName: `uploads/${file.name}`, maxSize: 100 * 1024 * 1024, partSize: 5 * 1024 * 1024, queueLength: 3, onUploadProgress: console.log, }); ``` OSS 浏览器端建议使用服务端签发的 STS 临时凭证,不建议把长期 AccessKey / SecretKey 写入前端代码。 ### 华为云 OBS ```ts import ObsClient from 'esdk-obs-browserjs'; import ObjectStorage, { ObjectStorageType } from 'object-storage-js'; const storage = new ObjectStorage({ type: ObjectStorageType.OBS, sdkObject: ObsClient, bucketName: 'example-bucket', endPoint: 'https://obs.cn-north-4.myhuaweicloud.com', accessKey: 'your-temporary-access-key-id', secretKey: 'your-temporary-secret-access-key', securityToken: 'your-security-token', }); await storage.upload({ file, fileName: `uploads/${file.name}`, maxSize: 100 * 1024 * 1024, partSize: 5 * 1024 * 1024, queueLength: 3, onUploadProgress: console.log, }); ``` OBS 小文件会通过 SDK 生成预签名 URL 后 PUT 上传,大文件会调用 OBS SDK 的 `uploadFile` 分片上传。 ### MinIO / AWS S3 ```ts import AWS from 'aws-sdk'; import ObjectStorage, { ObjectStorageType } from 'object-storage-js'; const minioStorage = new ObjectStorage({ type: ObjectStorageType.MINIO, sdkObject: AWS, bucketName: 'example-bucket', endPoint: 'https://minio.example.com', region: 'us-east-1', accessKey: 'your-access-key', secretKey: 'your-secret-key', }); await minioStorage.upload({ file, fileName: `uploads/${file.name}`, maxSize: 100 * 1024 * 1024, partSize: 5 * 1024 * 1024, queueLength: 3, onUploadProgress: console.log, }); ``` AWS S3 使用方式一致,只需要把 `type` 改为 `ObjectStorageType.AWS`,并按实际服务配置 `region`、`endPoint` 和临时凭证。`minio` 会默认开启 S3 path style。 ### 七牛云 Kodo ```ts import * as qiniu from 'qiniu-js'; import ObjectStorage, { ObjectStorageType } from 'object-storage-js'; const storage = new ObjectStorage({ type: ObjectStorageType.QINIU, sdkObject: qiniu, uploadToken, }); await storage.upload({ file, fileName: `uploads/${file.name}`, onUploadProgress: console.log, }); ``` 七牛云上传 token 应由服务端签发。浏览器端不应该持有 AccessKey / SecretKey。 ### 百度 BOS ```ts import baidubce from '@baiducloud/sdk'; import ObjectStorage, { ObjectStorageType } from 'object-storage-js'; const storage = new ObjectStorage({ type: ObjectStorageType.BOS, sdkObject: baidubce.sdk, bucketName: 'example-bucket', endPoint: 'https://bj.bcebos.com', signatureUrl: '/api/bos/signature', }); await storage.upload({ file, fileName: `uploads/${file.name}`, contentType: file.type, }); ```