文件分片上传 Filepond

应用场景

功能定位

FilePond 是一个灵活的文件上传库,可以拖入上传文件,并且会对图像进行优化以加快上传速度。让用户体验到出色、进度可见、如丝般顺畅的用户体验!能在大文件分片上传场景下,集成了上传、重传、删除等多种功能。

www.jianshu.com/p/1565067eb...

特点优势

  • 上传内容:支持目录、文件、多个文件、本地路径、远程 URL 等。
  • 文件管理:删除文件、选择文件、复制和粘贴文件、或使用 API 方式添加文件。
  • 上传方式:使用 AJAX 进行异步上传、或将文件编码为 base64 数据用表单发送、分片上传。
  • 图像优化:自动调整图像大小、裁剪和修复 EXIF 方向。
  • 响应式:可在移动和桌面设备上使用。
  • 插件:拥有多样、强大的插件,定制化不同需求

插件生态

FilePond 该库拥有多样、强大的插件部分,可以根据自己的需求选择插件组合起来使用,部分常用插件如下所示:

  • File Rename:重命名客户端上的文件
  • File Encode:将文件编码为 base64 数据
  • File size Validation:文件大小验证工具
  • File Type Validation:文件类型验证工具
  • File Metadata:限制要添加的文件类型
  • File Poster:在文件项目中显示图像
  • Image Preview:显示图像文件的预览
  • Image Edit:手动编辑图像文件
  • Image Crop:设置图像文件的裁剪比例
  • Image Resize:设置图像文件的输出尺寸
  • Image Transform:上传之前在客户端上图像变换
  • Image EXIF Orientation:提取 EXIF 方向信息
  • Image Size Validation:限制要添加的图像的尺寸
  • Image Filter:将颜色矩阵应用于图像像素

注:完整的插件列表及对应插件 API 文档链接,请查看 👇👇👇

pqina.nl/filepond/pl...

引入插件的基本步骤:

  1. 引入 CSS 文件(部分插件有 CSS 文件)
  2. 引入 JS 文件
  3. 注册插件
  4. 配置插件(部分插件需配置)

常用的插件使用方法:

  1. destroys:销毁实例
  2. find:返回附加提供的元素的实例
  3. getOptions:返回当前的配置项
  4. supported:鉴别浏览器是否支持 FilePond

生态环境

FilePond 作为一个出色的 JavaScript 库,其在不同项目框架、项目库中,有着出色且丰富的集成生态,如上图所示的 jQuery、React、Vue、Angular、Svelte 等。

我们重点关注 FilePond 本身!

filepond

名称 链接
npm www.npmjs.com/package/fil...
官网 pqina.nl/filepond/
github github.com/pqina/filep...

vue-filepond

名称 链接
npm www.npmjs.com/package/vue...
官网 pqina.nl/filepond/do...
github github.com/pqina/vue-f...

流程设计

上传基本流程

FilePond 异步上传文件,被成为 Processing: 简而言之,就是 FilePond 发送一个文件至服务端 server ,期望服务端返回一个唯一的文件 id(a unique file id)

下图详细介绍 Processing 的基本流程(以上传 my-file.png 为例)

  1. FilePondmultipart/form-data 形式,发送 POST 请求,上传文件 my-file.jpg
  2. server 将此文件保存在唯一的位置 tmp/12345/my-file.jpg
  3. servertext/plain 形式,返回给 FilePond 一个唯一位置 id 12345
  4. FilePond 把这个唯一位置 unique id 12345 ,存储至隐藏的 input 标签字段内
  5. client 用户提交包含带 unique idinput 选项的完整表单
  6. server 通过 unique id 移动 temp/12345 下的 my-file.jpg 文件,至最终位置 xxx 下,然后再移除掉原临时文件夹 tmp/12345

分片上传流程

  1. 为了以 切片(chunk) 形式上传文件(process file ),需要设置 chunkUploadstrue
  2. FilePond 会对大于 chunkSize 的文件,进行分片
  3. 对于小于 chunkSize 的文件,会被直接发送到 process 接口
  4. 若想强制所有文件都被以切片形式上传,只需设置 chunkForcetrue 即可

在 *分片上传场景(或称 Process Chunks) *下,在 接口请求中 需包含自定义 Header 如下:

Header Description
Upload-Length 被传输文件的总字节数
Upload-Name 被传输文件的名称
Upload-Offset 被传输切片的字节偏移量
Content-Type patch 请求的内容类型,设定为'application/offset+octet-stream'

简易流程

  1. FilePond 将通过发送一个 POST 请求(不带文件数据,并在请求头中携带 Upload-Length ),以开启分片上传!并期望从接口响应中拿到一个唯一的传输 id
  2. FilePond 将通过发送一个 PATCH 请求,向服务端推送一个切片。未来的每个切片推送请求,都将携带 Content-Type、Upload-Offset、Upload-Name、Upload-Length
  3. FilePond 将通过发送一个 HEAD 请求,获取哪些切片已经被上传,并期望从 响应头 中的 Upload-Offset 中,获取到下一个切片的文件偏移量

详细流程

  1. FilePondserver 请求一个唯一的传输 id(transfer id ),用来标识未来文件传输的唯一位置。这个请求默认以 POST 方法发送,并在请求头中携带要上传文件的总字节数,即 Upload-Length
  2. server 收到请求后,便会创建唯一的位置(目录)tmp/12345/ ,用于存放未来的文件切片
  3. server 将刚创建唯一位置,对应的 id 12345 ,以 text/plain 形式作为接口响应内容
  4. FilePond 拿到接口响应后,将其存储至 File Item(FilePond 对 file 的二次封装)

自此,命运的齿轮开始转动......

  1. FilePond 通过一个携带 unique id 12345PATCH 请求,开始上传第一个切片!所有切片上传的 PATCH 请求,都会在请求头中携带 Upload-Offset、Upload-Length、Upload-Name
  2. FilePond 在所有切片都被成功上传前,会依次发送切片上传请求
  3. server 在所有切片都被上传成功后,会主动根据切片,创建文件
  4. 当所有切片都被成功上传,FilePond 会将 unique id 12345 存储至 <fieldset > 标签下的 <input > 中,作为该文件的 server id(用于 revert/remove 等操作)
  5. (非必须) client 提交 FilePond 表单( 下所有的 上的 unique id)
  6. server 通过 unique id ,移动 tmp/12345/my-file.jpg 到最终的目标位置,并将删除临时文件夹 tmp/12345

如果过程中,有一个切片上传失败了!FilePond 默认会重试 3 次(chunkRetryDelays 为 [500,1000,3000] )

若在 3 次重试,仍失败,重试的权利则交给用户

用户重试时,FilePond 会这样处理:

  1. 因为 FilePond 会记住在上传过程中,先前的 transfer id 12345 ,重试时,FilePond 会以一个 HEAD 请求开始,并在请求 URL 中,携带该 transfer id
  2. server 响应该请求时,在响应头中,携带期望的下一个切片的字节偏移量 Upload-Offset
  3. FilePond 将所有具有低于 Upload-Offset 偏移量的块标记为已完成,并从请求偏移量处,继续上传块

如下图所示:

常用 API

导出模块 Exports

我们在项目中,通过 import 导入 filepond 后,得到的是一个 完整的对象 FilePond,该对象暴露(export)了多类模块。

引入这些导出的模块,有下面的两种方式(以导入 supported 方法为例)

  1. 方式一
js 复制代码
import FilePond from 'filepond'

const supported = FilePond.supported
  1. 方式二
js 复制代码
import { supported } from 'filepond'

暴露的导出模块,常常以 方法(Methods )、枚举(Enums)的形式存在

方法 Methods

Method Description
create(element, options) 创建一个 FilePond 实例,两个入参都是可选,非必填的
destroy(element) 销毁绑定在指定元素上的 FilePond 实例
find(element) 查找绑定在指定元素上的 FilePond 实例
parse(context) 解析 class 含 .filepond 的 DOM 片段,并将其转换为 FilePond 元素
registerPlugin(plugin) 注册一个 FilePond 插件,以供后用
setOptions(options) 为 FilePond 实例,设置页面级别默认配置 options
getOptions() 返回当前默认配置 options
supported() 判断当前浏览器是否支持 FilePond
javascript 复制代码
import { supported } from 'filepond'

const can = supported() // 判断当前浏览器是否支持 FilePond

console.log(can)
typescript 复制代码
<input type="file" class="filepond" />

<script>
  FilePond.parse(document.body);
</script>

枚举 Enums

Property Description
Status 与 FilePond 的 status 属性,共同使用,决定当前 FilePond 实例的状态
FileOrigin File Itemorigin 属性,共同使用,决定 File Item 的来源
FileStatus File Itemstatus 属性,共同使用,决定 File Item 的状态
OptionTypes
yaml 复制代码
{
    EMPTY: 0,
    IDLE: 1,
    ERROR: 2,
    BUSY: 3,
    READY: 4
}
yaml 复制代码
{
    INIT: 1,
    IDLE: 2,
    PROCESSING_QUEUED: 9,
    PROCESSING: 3,
    PROCESSING_COMPLETE: 5,
    PROCESSING_ERROR: 6,
    PROCESSING_REVERT_ERROR: 10,
    LOADING: 7,
    LOAD_ERROR: 8
}
arduino 复制代码
{
    INPUT: 1, // INPUT by the user
    LIMBO: 2, // Restored from the server as a temporary file
    LOCAL: 3  // 是本地服务器文件,已上传并确认不在服务器临时上传文件夹中的文件
};

文件信息 File Item

FileFond 实例的 addFile、getFile、processFile 方法,返回的都是 FileItem 对象。

请注意:FileItem 对象,是 FilePond 内部,对文件本身的二次封装定义,携带了与 FilePond 强相关的独特属性和方法!

Getters

Property Description
id 文件的 id
serverId 文件的 server id
origin 文件的 origin,有以下几种类型:1. input (由用户添加)
  1. limbo(临时的服务器文件)
  2. local(现有的服务器文件) | | status | 文件的当前状态,由枚举 FilePond.FileStatus 来决定 | | file | 文件 File 对象 | | fileExtension | 文件的拓展类型 extension | | fileSize | 文件的大小 size | | filename | 文件的全名(含拓展类型 extension) | | filenameWithoutExtension | 不含拓展的文件名 |

Methods

Method Description
abortLoad() 中止加载该文件
abortProcessing() 中止处理该文件
getMetadata(key?) 按 key 检索保留在文件中的元数据,若没有 key,则返回完整的元数据
setMetadata(key, value) 为文件添加额外的元数据

组件实例 Instance

每个 FilePond 实例,都有一些列方法、属性、和事件,使得在项目中的集成,变得很容易

属性 Properties

A list of properties to read from and write to the current state of FilePond.

The FilePond instance exposes a set of properties that enable us to update its state.

核心属性

FilePond 模块暴露了下面的核心属性

Property Default Value Description
element null 1. FilePond 实例的根元素
  1. 无 setter | | status | 0 | 1. FilePond 实例的状态
  2. 无 setter | | name | 'filepond' | 1. [ ] 标签的 name 属性
  3. 同时也作为 输入字段名称 | | className | null | 为 FilePond 实例的根元素,添加额外的 class 类名 |
filepond 使用示例
xml 复制代码
<template>
  <input ref="vue-filepond" type="file" />
</template>

<script>
import { create } from 'filepond'
import 'filepond/dist/filepond.min.css'

export default {
  name: 'LargeFileUpload',
  mounted() {
    const el = this.$refs['vue-filepond'] // FilePond 根元素

    this.filePond = create(el, {
      name: 'File',
      credits: [],
      className: 'tf-vue-filepond-root'
    }) // FilePond 实例
  }
}
</script>
Property Default Value Description
required false 将输出字段设为必填
disabled false 将输出字段设为禁用
captureMethod null 设置 capture 属性
files A list of file locations that should be loaded Immediately 应立即加载的文件位置列表
allowRevert true 是否启用重试按钮the revert processing button ?
allowRemove true
allowProcess true
allowReorder
Server 类属性
Property Default Value Description
server null A server configuration object describing how FilePond should interact with the server.
instantUpload true 是否将文件立即上传到服务器
chunkUploads false 启用分块上传,启后会在上传前自动将文件切成 chunkSize 块
chunkForce false 对于小于设置的 chunkSize 的文件也强制使用块
chunkSize 5000000 块的大小(以字节为单位)
chunkRetryDelays [500,1000,3000] 重新上传的延迟时间
Callbacks 类属性
Property Function
oninit() FilePond 实例已被创建,并已完成初始化
onwarning(error[, file, status]) FilePond 抛出警告
onerror(error[, file, status]) FilePond 抛出异常
oninitfile(file) 已创建文件的 File Item
Property Function
onaddfilestart(file) 已开始文件加载 Started file load
onaddfileprogress(file, progress) 加载文件取得进展 Made progress loading a file
onaddfile(error, file) 无报错时,表示文件已被成功加载
Hooks 类属性
Property Description
beforeDropFile(file) 拖拽文件前的钩子,返回 false 标识阻止拖拽(支持返回 boolean 或 promise)
beforeAddFile(item) 添加文件前的钩子,返回 false 表示阻止添加(支持返回 boolean 或 promise)
beforeRemoveFile(item) 删除文件前的钩子,返回 false 表示阻止删除(支持返回 boolean 或 promise)

常见问题

css 构建失败

github.com/pqina/vue-f...

相关推荐
拉不动的猪1 小时前
刷刷题39(同一组件中的不同的标签页如何实现通信)
前端·javascript·面试
拉不动的猪1 小时前
刷刷题37(vue3的优化点)
前端·javascript·面试
家里有只小肥猫2 小时前
关于新奇的css
前端·css
南雨北斗2 小时前
jquery ajax 返回TP6错误信息的调试方法
前端·后端
星星不打輰2 小时前
css的显示模式
前端·css
代码CC2 小时前
Vue.js+Element UI 登录界面开发详解【附源码】
前端·vue.js·ui·elementui
无名之逆2 小时前
Hyperlane:Rust 语言打造的 Web 后端框架新标杆
开发语言·前端·网络·网络协议·rust·github·ssl
冰夏之夜影2 小时前
【css酷炫效果】纯CSS实现悬浮弹性按钮
前端·css
shadouqi2 小时前
4.angular 服务
前端·javascript·angular.js
努力往上爬de蜗牛2 小时前
react学习1.搭建react环境
javascript·学习·react.js