npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

kj-uploader-service

v0.1.14

Published

前端可复用的文件上传服务,支持COS高级上传、STS签名、并发控制及控制方法

Readme

kj-uploader-service 使用文档(中文)

本服务提供浏览器端文件上传到腾讯云 COS 的封装,支持:

  • STS 临时密钥自动获取与到期前刷新
  • 高级上传(简单/分片自动选择)、并发队列与失败自动重试
  • 暂停、继续、取消、按 key 重试
  • 获取带签名的下载链接
  • 媒体截帧:获取快照访问 URL 与快照图片内容

安装与引入

  • 依赖:cos-js-sdk-v5blueimp-md5(作为 peerDependencies)
  • 方式:直接引入源码或打包后的 dist
import { FileUploader, triggerDownload, triggerDownloadBatch } from 'kj-uploader-service'

构造与配置

使用 new FileUploader(config) 创建实例。

配置 UploaderConfig

| 字段 | 类型 | 必填 | 说明 | | ------------------ | ---------------------------------------- | ---- | ---------------------------------------------------- | | apiEndpoint | string | 是 | STS 接口地址(服务端提供临时密钥) | | appCode | string | 是 | 业务标识(服务端使用) | | maxConcurrent | number | 否 | 最大并发上传数,默认 3 | | chunkSize | number | 否 | 分片大小(字节),默认 5MB | | retryTimes | number | 否 | 失败自动重试次数,默认 2 | | prefixOverride | string | 否 | 上传前缀覆盖(非空生效,否则回退后端前缀) | | stsHeaders | Record<string,string> | 否 | 仅用于 STS 接口的自定义请求头 | | cosHeaders | Record<string,string> | 否 | 用于 COS 高级上传的 Headers | | signConfig | { appKey: string; version?: string } | 否 | STS 签名配置(内置算法使用,默认 version=1.0.0) |

上传参数 UploadOptions

| 字段 | 类型 | 必填 | 说明 | | -------------- | ---------------------------------- | ---- | ---------------------------------------------- | | onBefore | (ctx: { key: string }) => void | 否 | 上传开始前回调,可获取即将使用的对象 key | | onProgress | (pd: ProgressData) => void | 否 | 进度回调,见下方 ProgressData | | signal | AbortSignal | 否 | 取消信号(本地即时取消) | | headers | Record<string,string> | 否 | 覆盖 COS 上传时的 Headers | | Bucket | string | 否 | 覆盖目标桶(默认使用后端返回) | | Region | string | 否 | 覆盖地域(默认使用后端返回) | | Key | string | 否 | 覆盖对象 Key(默认按前缀/日期/文件名自动生成) | | SliceSize | number | 否 | 触发分片阈值(默认 5MB) | | ChunkSize | number | 否 | 分片大小(默认取实例的 chunkSize) |

进度结构 ProgressData

| 字段 | 类型 | 说明 | | -------------- | ---------- | ---------------------------------- | | fileId | string | 内部任务标识(用于并发管理) | | key | string | 对象存储 Key(用于 UI 显示与控制) | | percentage | number | 进度百分比(0~1) | | loaded | number | 已上传字节数 | | total | number | 总字节数 |

媒体截帧参数 SnapshotQuery

| 字段 | 类型 | 必填 | 说明 | | ---------- | ----------------------------- | ---- | ------------------------------- | | time | number | 是 | 截图时间点(秒) | | width | number | 否 | 截图宽,默认 0 | | height | number | 否 | 截图高,默认 0 | | format | 'jpg' \| 'png' | 否 | 图片格式,默认 'jpg' | | rotate | 'auto' \| 'off' | 否 | 旋转,默认 'auto' | | mode | 'keyframe' \| 'exactframe' | 否 | 截帧方式,默认 'exactframe' |

公共方法

upload(file, opts?)

  • 说明:上传单个文件(支持 File 对象或 Base64 字符串)

参数:

| 名称 | 类型 | 说明 | | -------- | ----------------- | ------------------------------------------------------------ | | file | File \| string | 需上传的浏览器文件对象,或 Base64 字符串(自动解析 MIME 转 Blob) | | opts | UploadOptions | 可选配置,见上文 |

返回:

| 字段 | 类型 | 说明 | | ------------ | ---------- | -------------------------------------- | | key | string | 对象存储 Key | | url | string | 带签名的访问链接(有效期默认 3600 秒) | | metadata | any | COS 上传返回的原始数据 |

示例:

const res = await uploader.upload(file, {
  onBefore: ({ key }) => console.log('key:', key),
  onProgress: (pd) => console.log(pd.percentage)
})
console.log(res.url)

uploadBatch(files)

  • 说明:批量上传,将文件逐一入队并按并发限制执行

参数与返回:

| 名称 | 类型 | 说明 | | --------- | ----------------------------------------------------- | ---------------------------------- | | files | File[] | 文件列表 | | 返回 | { cancel(fileId), pause(fileId), resume(fileId) } | 控制器,按内部 fileId 控制任务 |

cancel(key)

  • 说明:按对象 key 取消上传任务

| 名称 | 类型 | 说明 | | ------- | ---------- | -------- | | key | string | 对象 Key |

pause(key) / resume(key)

  • 说明:按对象 key 暂停/继续上传任务

| 名称 | 类型 | 说明 | | ------- | ---------- | -------- | | key | string | 对象 Key |

retryByKey(key, opts?)

  • 说明:按对象 key 重试上传(重置该任务的重试计数后重新执行)

| 名称 | 类型 | 说明 | | -------- | ----------------- | -------- | | key | string | 对象 Key | | opts | UploadOptions | 可选配置 |

download(key, expires?)

  • 说明:获取带签名的下载链接

| 名称 | 类型 | 说明 | | ----------- | ---------- | ----------------------------- | | key | string | 对象 Key | | expires | number | 链接有效期秒数,默认 3600 |

返回:Promise<string>

downloadObject(key, opts?)

  • 说明:下载对象的二进制内容(支持限速与进度)

参数:

| 名称 | 类型 | 说明 | | -------- | ----------------------------------------------------------------------------------------------------------------------------- | -------- | | key | string | 对象 Key | | opts | { Bucket?: string; Region?: string; headers?: Record<string,string>; trafficLimit?: number; onProgress?: (pd:any)=>void } | 可选配置 |

返回:Promise<Blob | ArrayBuffer>

说明:如需限速,设置 trafficLimit(bit/s),范围 819200 - 838860800;或在 headers 中传入 x-cos-traffic-limit

示例:

// 限速 800Kb/s 下载对象内容
const body = await uploader.downloadObject('1.jpg', { trafficLimit: 819200, onProgress: (pd) => console.log(pd.percent) })
const objectUrl = URL.createObjectURL(body as Blob)

triggerDownload(url, fileName?)

  • 说明:触发浏览器下载(自动拼接 response-content-disposition 参数)
  • 备注:此方法也可直接从包中引入使用,无需实例化 FileUploader

| 名称 | 类型 | 说明 | | ---------- | -------- | ---------------- | | url | string | 文件的访问 URL | | fileName | string | 下载时的保存文件名 |

triggerDownloadBatch(files, interval?)

  • 说明:批量触发下载,内置间隔延迟以避免浏览器拦截
  • 备注:此方法也可直接从包中引入使用,无需实例化 FileUploader

| 名称 | 类型 | 说明 | | ---------- | ----------------------------------------- | ---------------------------------- | | files | { url: string; fileName?: string }[] | 文件列表 | | interval | number | 两次下载间的延迟(毫秒),默认 1000 |

snapshotUrl(key, query, opts?)

  • 说明:生成媒体截帧访问 URL(带签名与查询参数)

参数:

| 名称 | 类型 | 说明 | | --------- | ---------------------------------------------------------- | ----------------------- | | key | string | 媒体文件对象 Key | | query | SnapshotQuery | 截帧参数 | | opts | { Bucket?: string; Region?: string; expires?: number } | 可选覆盖桶/地域与有效期 |

返回:Promise<string>(可直接用于 <img src="...">

示例:

const url = await uploader.snapshotUrl('video.mp4', { time: 1, format: 'jpg' })

snapshot(key, query, opts?)

  • 说明:获取媒体截帧图片内容(二进制)

参数:

| 名称 | 类型 | 说明 | | --------- | ------------------------------------------------------ | ---------------- | | key | string | 媒体文件对象 Key | | query | SnapshotQuery | 截帧参数 | | opts | { Bucket?: string; Region?: string; dataType?: 'blob' | 'arraybuffer' } |

返回:Promise<Blob | ArrayBuffer>

示例:

const blob = await uploader.snapshot('video.mp4', { time: 1, width: 320, height: 180 })
const imgUrl = URL.createObjectURL(blob as Blob)

mediaInfo(key, opts?)

  • 说明:获取媒体文件的信息(视频元数据),由 COS CI 返回

参数:

| 名称 | 类型 | 说明 | | -------- | ---------------------------------------- | ------------------------------- | | key | string | 媒体文件对象 Key | | opts | { Bucket?: string; Region?: string } | 覆盖桶/地域(默认使用后端返回) |

返回:Promise<any>(COS 返回的数据结构,通常包含媒体格式、流信息等)

示例:

const info = await uploader.mediaInfo('video.mp4')
console.log(info)

设计与行为说明

  • 临时密钥:
    • 到期前 60 秒自动刷新
    • 接口请求失败时,内部自动执行指数退避重试(最多 3 次,间隔 1s/2s/4s...),防止网络抖动导致的上传失败
    • 使用前会双重校验是否过期并重建实例
  • 前缀覆盖:仅在 prefixOverride 非空且去掉空白后仍有内容时生效,否则回退后端前缀
  • 优先级:上传时 opts 覆盖 > 实例配置 > 后端返回默认值
  • 失败重试:线性退避 500ms × attempts,最多 retryTimes
  • 并发队列:限制同时运行的任务数,任务完成后自动触发下一项
  • 进度回调:同时提供 fileIdkey,避免 UI 匹配不一致
  • Base64 上传:若传入 Base64 字符串,会自动解析 MIME 类型并转换为 Blob,文件名为自动生成的随机 ID

常见问题

  • CORS:需在 COS 控制台正确配置跨域,AllowHeader: *ExposeHeaders 包含 ETagContent-Length
  • SDK 环境:请在浏览器环境使用 cos-js-sdk-v5,Node 环境请改用 cos-nodejs-sdk-v5
  • 要使自定义CDN域名访问时也能自动触发下载,需要在URL后拼接参数 response-content-disposition=attachment。具体方法如下: 在获取的URL后补充参数: url + (url.indexOf('?') > -1 ? '&' : '?') + 'response-content-disposition=attachment' 如果需要重命名下载文件,可拼接: url + (url.indexOf('?') > -1 ? '&' : '?') + 'response-content-disposition=attachment;filename=自定义文件名'