Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wechat-miniprogram/miniprogram-file-uploader
https://github.com/wechat-miniprogram/miniprogram-file-uploader
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/wechat-miniprogram/miniprogram-file-uploader
- Owner: wechat-miniprogram
- License: mit
- Created: 2020-07-06T06:17:48.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2021-03-24T03:30:53.000Z (almost 4 years ago)
- Last Synced: 2024-04-24T23:21:28.536Z (8 months ago)
- Language: JavaScript
- Size: 75.2 KB
- Stars: 57
- Watchers: 4
- Forks: 16
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# miniprogram-file-uploader
小程序大文件上传库。
小程序中的上传文件 [`wx.uploadFile`](https://developers.weixin.qq.com/miniprogram/dev/api/network/upload/wx.uploadFile.html) 接口有大小限制(10M),采用分块上传的方式进行解决。该上传库依赖 [`FileSystemManager.readFile`](https://developers.weixin.qq.com/miniprogram/dev/api/file/FileSystemManager.readFile.html) 接口进行文件的分块读取,基础库版本 `2.10.0` 及以上支持,可通过 `isSupport` 接口判断。
## 支持的特性
* [x] 分块读取,可限制占用内存大小
* [x] 分块并发上传
* [x] 支持暂停、恢复、取消、重传
* [x] 支持秒传,计算md5判断服务端是否已存在
* [x] 支持进度、预估剩余时间、平均速度、出错自动重试
* [x] 错误处理## 安装
通过 `npm` 安装
```bash
npm i miniprogram-file-uploader
```## 使用
创建一个 `uploader` 实例:
```js
if (Uploader.isSupport()) {
const uploader = new Uploader({
tempFilePath,
totalSize: size,
uploadUrl: UPLOAD_URL,
mergeUrl: MERGE_URL,
})uploader.upload()
}
```实例化后可以选择监听一些事件:
```js
// 成功或失败都会触发
uploader.on('complete', (res) => {
console.log('upload complete', res)
})// 文件上传成功
uploader.on('success', (res) => {
console.log('upload success', res)
})// 文件上传失败
uploader.on('fail', (res) => {
console.log('fail', res)
})// 文件进度变化
uploader.on('progress', (res) => {
this.setData({
progress: res.progress,
uploadedSize: parseInt(res.uploadedSize / 1024),
averageSpeed: parseInt(res.averageSpeed / 1000),
timeRemaining: res.timeRemaining
})
})
```## 服务端如何接收
由于小程序端采用分块上传,服务端也需要进行秒传验证、接收分块、分块合并等处理,可参考 `example/server/app.js` 的实现,共涉及到三个接口:
1. 秒传验证 (`verifyUrl: Get`)
当配置项 `testChunks` 为 `true` 时,小程序端会预先发送一个验证请求,利用 `spark-md5` 根据文件内容计算出唯一标识,服务端可根据该值判断是否已经上传,或者上传了部分分片,并返回给前端。小程序端依此可以实现续传或秒传的效果。需注意的是,计算文件的 `hash` 值也有一定的时间和内存损耗。
#### 请求参数
| 属性 | 类型 | 说明 |
| ---------- | ------ | ------------- |
| identifier | `String` | 文件的 md5 值 |
| fileName | `String` | 文件名 |#### 返回参数
| 属性 | 类型 | 说明 |
| -------------- | ------- | ---------------------------------- |
| url | `String` | 已上传时返回线上文件路径 |
| needUpload | `Boolean` | 是否需要上传 |
| uploadedChunks | `Array` | 未完全上传时,返回已上传的分块序号 |2. 接收分块 (`uploadUrl: Post`)
小程序端采用 [`wx.request`](https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html) 接口发送文件的二进制数据,`content-type` 为 `application/octet-stream`,服务端接收后放入暂存区,收到合并请求后进行合并。
上传接口的 `query` 中包含如下分块信息:
* `identifier`:文件的唯一标识
* `index`:分块的序号,从 0 开始
* `chunkSize`: 分块大小,最后一块可能小于该值
* `fileName`:文件名,传入的文件名
* `totalChunks`:分块的总数量,依据 `chunkSize` 计算
* `totalSize`:文件总大小3. 合并分块 (`mergeUrl: Get`)
分块全部发送后,小程序端发送合并请求,服务端按分片序号进行合并,返回最终的文件线上路径。
#### 请求参数
| 属性 | 类型 | 说明 |
| ---------- | ------ | ------------- |
| identifier | `String` | 文件的 md5 值 |
| fileName | `String` | 文件名 |#### 返回参数
| 属性 | 类型 | 说明 |
| ---- | -------- | ------------ |
| url | `String` | 线上文件路径 |对于每个请求,小程序端依据配置 `successStatus` 、 `failStatus` 和返回的 `statusCode` 判断成功或失败。
* `200`, `201`, `202`: 请求成功
* `404`, `415`, `500`, `501`: 请求失败,会终止文件上传
* 其他状态码: 出错了,但是会自动重试## API 文档
### Uploader
#### 配置项
实例化的时候可以传入配置项:
```js
const uploader = new Uploader(option)
```
| 配置项 | 必填 | 类型 | 说明 |
| ------------------ | ---- | ------- | ---------------------------------------------------------------------------------- |
| tempFilePath | 是 | String | 小程序内的文件临时路径 |
| totalSize | 是 | Number | 文件的总大小,单位 B |
| verifyUrl | 否 | String | 秒传验证接口 |
| uploadUrl | 是 | String | 接收分块接口 |
| mergeUrl | 是 | String | 合并分块接口 |
| maxConcurrency | 否 | Number | 并发上传数,默认 5,最大不超过 10 |
| generateIdentifier | 否 | Function | 可覆盖默认的生成文件唯一标识的函数,需返回 identifier |
| chunkSize | 否 | Number | 分块大小,默认 5 * 1024 * 1204 B |
| maxMemory | 否 | Number | 加载文件最大占用的内存,默认 100 * 1024 * 1024 B,内存占用过大时可能导致小程序闪退 |
| query | 否 | Object | 上传分块时可添加自定义的参数 |
| header | 否 | Object | 上传分块时可添加自定义的请求头 |
| testChunks | 否 | Boolean | 是否需要进行秒传验证,默认为 false |
| maxChunkRetries | 否 | Number | 请求失败时最大重试次数,默认为 0 |
| chunkRetryInterval | 否 | Number | 自动重试间隔,默认为 0 |
| timeout | 否 | Number | 请求超时时间,默认 10000 ms |
| successStatus | 否 | Array | 认为响应式成功的响应码,默认 [200, 201, 202] |
| failStatus | 否 | Array | 认为是出错的响应码,默认 [404, 415, 500, 501] |
| verbose | 否 | Boolean | 是否输出开始日志,默认 false |#### 方法
* .on(event, callback) 监听事件
* .off(event, callback) 移除事件监听
* .upload() 开始上传
* .pause() 暂停上传
* .resume() 继续上传,与 `pause` 配对使用
* .cancel() 取消所有上传文件,与 `upload` 配对使用
* .isSupport() 当前小程序版本是否支持#### 事件
通过 `on` 方法进行监听
* `success`,上传成功时触发,`e = {errCode: 0, url: 'xxx'}`
* `fail`,上传失败时触发,`e = {errCode: 0, errMsg: 'xxx'}`
* `complete`,上传成功或失败时触发,返回值同 `success` 或 `fail`
* `retry`,请求重传时触发,`e = {statusCode: 302, url: 'xxx'}`
* `progess`,上传进度变化时触发,返回内容如下:| 属性 | 类型 | 说明 |
| ------------- | ------ | ----------------------- |
| totalSize | Number | 文件的总大小,单位 B |
| progress | Number | 上传进度,范围 [0, 100] |
| uploadedSize | Number | 已上传大小,单位 B |
| averageSpeed | Number | 平均速度,单位 B/s |
| timeRemaining | Number | 预估剩余时间,单位 ms |## 注意事项
1. 由于 `wx.requst` 没有 `progressUpdate` 事件,这里的 `progress` 事件在收到分块请求结果后触发;
2. 真机 `chooseVideo` 返回的临时文件,每次计算 md5 值不同,无法使用秒传功能;
3. 真机缺少 `console.timeEnd` 方法,部分开发日志会打印不出来;## 开发
```js
# 安装依赖
npm install# 启动 example 中的服务,监听文件改动
npm run dev# 编译
npm run build
```