Coder Social home page Coder Social logo

miniprogram-file-uploader's Introduction

miniprogram-file-uploader

小程序大文件上传库。

小程序中的上传文件 wx.uploadFile 接口有大小限制(10M),采用分块上传的方式进行解决。该上传库依赖 FileSystemManager.readFile 接口进行文件的分块读取,基础库版本 2.10.0 及以上支持,可通过 isSupport 接口判断。

支持的特性

  • 分块读取,可限制占用内存大小
  • 分块并发上传
  • 支持暂停、恢复、取消、重传
  • 支持秒传,计算md5判断服务端是否已存在
  • 支持进度、预估剩余时间、平均速度、出错自动重试
  • 错误处理

安装

通过 npm 安装

npm i miniprogram-file-uploader

使用

创建一个 uploader 实例:

if (Uploader.isSupport()) {
  const uploader = new Uploader({
    tempFilePath,
    totalSize: size,
    uploadUrl: UPLOAD_URL,
    mergeUrl: MERGE_URL,
  })

  uploader.upload()
}

实例化后可以选择监听一些事件:

// 成功或失败都会触发
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)

当配置项 testChunkstrue 时,小程序端会预先发送一个验证请求,利用 spark-md5 根据文件内容计算出唯一标识,服务端可根据该值判断是否已经上传,或者上传了部分分片,并返回给前端。小程序端依此可以实现续传或秒传的效果。需注意的是,计算文件的 hash 值也有一定的时间和内存损耗。

请求参数

属性 类型 说明
identifier String 文件的 md5 值
fileName String 文件名

返回参数

属性 类型 说明
url String 已上传时返回线上文件路径
needUpload Boolean 是否需要上传
uploadedChunks Array<Number> 未完全上传时,返回已上传的分块序号
  1. 接收分块 (uploadUrl: Post)

小程序端采用 wx.request 接口发送文件的二进制数据,content-typeapplication/octet-stream,服务端接收后放入暂存区,收到合并请求后进行合并。

上传接口的 query 中包含如下分块信息:

  • identifier:文件的唯一标识
  • index:分块的序号,从 0 开始
  • chunkSize: 分块大小,最后一块可能小于该值
  • fileName:文件名,传入的文件名
  • totalChunks:分块的总数量,依据 chunkSize 计算
  • totalSize:文件总大小
  1. 合并分块 (mergeUrl: Get)

分块全部发送后,小程序端发送合并请求,服务端按分片序号进行合并,返回最终的文件线上路径。

请求参数

属性 类型 说明
identifier String 文件的 md5 值
fileName String 文件名

返回参数

属性 类型 说明
url String 线上文件路径

对于每个请求,小程序端依据配置 successStatusfailStatus 和返回的 statusCode 判断成功或失败。

  • 200, 201, 202: 请求成功
  • 404, 415, 500, 501: 请求失败,会终止文件上传
  • 其他状态码: 出错了,但是会自动重试

API 文档

Uploader

配置项

实例化的时候可以传入配置项:

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,上传成功或失败时触发,返回值同 successfail
  • 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 方法,部分开发日志会打印不出来;

开发

# 安装依赖
npm install

# 启动 example 中的服务,监听文件改动
npm run dev

# 编译
npm run build

miniprogram-file-uploader's People

Contributors

juneandgreen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

miniprogram-file-uploader's Issues

合并分块怎么设置header?

后台需要携带token,在header里设置了,但是只能使用在接受分块接口,到合并分块就没有header了,要怎么配置?

Typescript如何引入该包

使用Typescript编写小程序时,安装该包的同时,还必须引入对应的声明文件,如何获取声明文件Uploader.d.ts?

并发请求问

能不能支持下 每次并发请求发送成功后,再次并发发送下一组。比如切块10个,一次并发3个,等3个都发送成功后,再次并发发送3个呢

模拟器上传视频报错

开发语言ts

错误信息如下:

errCode: 10001, errMsg: "readFile:fail permission denied, open "

image

安卓真机报错:

errCode: 10001, errMsg: "readFile:fail invalid path "

支持多个new Uploader实例吗?

在循环上传文件的时config中的mergeUrl、query始终为一个值,未根据列表设置
weiXinNewUpload(taskInfo,fileIdx,taskIdx){
let mergeUrl = this.$setting.baseURL + '/' + this.$setting.ms_sobey_api +"material/v2/upload/multipart/weixin/merge";
mergeUrl += ((mergeUrl.indexOf('?') == -1) ? '?' : '&') + 'access_token=' + this.vuex_token.access_token;
mergeUrl += ((mergeUrl.indexOf('?') == -1) ? '?' : '&') + 'taskId=' + taskInfo.taskId;
mergeUrl += ((mergeUrl.indexOf('?') == -1) ? '?' : '&') + 'province=' + this.vuex_user.province;
let current = this.uploadTaskList[taskIdx];
let uploadConfig = {};
uploadConfig = {
tempFilePath:!current.file.tempFilePath?current.file.path:current.file.tempFilePath,
totalSize: current.file.size,
fileName: current.file.name,
uploadUrl: this.uploadBaseUrl,
mergeUrl: mergeUrl,
testChunks: false,
verbose: true,
chunkSize:210241024,
maxConcurrency:3,
timeout:600000,
chunkRetryInterval:5000,
maxChunkRetries:5,
header: {
Method: "POST",
Authorization:'Bearer ' + this.vuex_token.access_token
},
query: {
fileId:taskInfo.fileId,
taskId:taskInfo.taskId
}
}
let uploader = new Uploader(uploadConfig);
this.uploadTaskList[taskIdx].uploader = uploader;
uploader.upload();
uploader.on("success",(res)=>{
console.log(res)
if(!res.code){
let groupType = this.fileTypeCheck(current.file.name);
let params = {
title: current.file.name,
catalogId: this.catalogChildrenId,
groupType: groupType,
sort: 1,
deptId: this.vuex_user.orgCode,
deptName: this.vuex_user.orgName,
isPublic: 0,
fileId: taskInfo.fileId,
filePath: res.data, //url
fileIdx
}
this.savaFile(params);
}else{
uploader.pause();
this.fileList[fileIdx].isError = true;
}
})
// 文件进度变化
uploader.on('progress', (res) => {
console.log("progress",res);
this.fileList[fileIdx].percent = res.progress;
this.$forceUpdate();
})
// 文件上传失败
uploader.on('fail', (res) => {
console.log('fail', res)
uploader.pause();
this.fileList[fileIdx].isError = true;
})
},

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.