Uppy 核心
Uppy
可以作为一个具有众多功能的上传器和界面。功能可以通过插件递增添加,但 Uppy
可以根据你的需求尽可能地精简。因此,我们构建了 Uppy 的核心,@uppy/core
,作为一个独立的协调器。它充当状态管理器、事件发射器和限制处理器。
何时应该使用它?
@uppy/core
是 Uppy 生态系统的基石,是所有添加插件的协调者。无论你寻找的是哪种上传体验,一切都从安装这个插件开始。
你可以使用 @uppy/core
并 构建自己的 UI 或选择使用 Dashboard 集成。对于上传插件,你可以参考 选择你需要的上传器 。
如果你想看看这一切是如何结合在一起的,请查看 示例 。
安装
npm
yarn
CDN
谨慎
该捆绑包包含了大部分Uppy
插件,因此这种方法不建议在生产环境中使用,因为当您实际上可能只使用少数几个插件时,您的用户却需要下载所有插件。 但在加速开发环境方面,它非常有用,所以不妨在开始时使用它来提高效率。
使用
@uppy/core
有四个导出:Uppy
、UIPlugin
、BasePlugin
和 debugLogger
。默认导出是 Uppy
类。
使用 Uppy 文件
Uppy 使用浏览器的 File
API 在状态中保存文件,但它被包装在 Object
中以便能够向其添加更多数据,我们称之为Uppy 文件。所有这些属性对插件和副作用(如 事件 )都非常有用。
修改这些属性应通过 方法 进行。
Uppy 文件属性
file.source
负责添加此文件的插件的名称。通常是像
'GoogleDrive'
这样的远程提供程序插件或像'DragDrop'
这样的 UI 插件。
file.id
文件的唯一 ID。
file.name
文件的名称。
file.meta
包含每个文件的标准以及用户定义元数据的对象。任何自定义文件元数据都应该是可 JSON 序列化的。以下标准元数据将存储在所有文件对象上,但插件可能会添加更多元数据。
file.meta.name
- 与
file.name
相同。file.meta.type
- 与
file.type
相同。file.meta.relativePath
- 对于任何通过拖放或在 Uppy 中打开的本地文件夹,文件夹内的文件将具有
relativePath
元数据字段设置为其相对于文件夹的路径。relativePath
以文件夹的名称开始并以文件的名称结束。如果直接拖放或打开文件,relativePath
将为null
。远程(提供程序)文件也存在相同的行为,但路径将是相对于用户的选中项(复选框)的。没有前导或尾随斜杠。- 本地文件示例: 当拖放名为
folder1
的本地文件夹时,该文件夹内有一个名为folder2
的文件夹,而folder2
内有一个名为file
的文件,该文件的relativePath
元数据字段将为folder1/folder2/file
。然而,如果直接拖放或打开file
,relativePath
将为null
。- 远程文件示例: 假设我们有一个远程提供程序文件结构,如
/folder1/folder2/file
。然后,如果用户勾选了folder1
旁边的复选框,file
的relativePath
将是"folder1/folder2/file"
。但是,如果用户首先导航到folder1
,然后才勾选folder2
旁边的复选框,relativePath
将是"folder2/file"
。file.meta.absolutePath
absolutePath
元数据字段仅对远程文件设置。无论用户选择如何,它始终相对于提供程序文件列表的根目录,即用户所见的那样。absolutePath
总是以/
开头,并且始终以文件名结束。澄清:absolutePath
和relativePath
之间的区别在于,absolutePath
仅存在于远程文件中,并且总是拥有文件的完整路径,而relativePath
是相对于用户所选文件夹的文件路径。
file.type
文件的 MIME 类型。如果用户浏览器未提供文件类型,这实际上可能是猜测的,因此这是一个尽力而为的值,并不能保证完全正确。
file.data
对于本地文件,这是代表文件内容的实际
File
或Blob
对象。 对于从远程提供程序导入的文件,文件数据在浏览器中不可用。
file.progress
包含上传进度数据的对象。
属性
bytesUploaded
- 到目前为止已上传的字节数。bytesTotal
- 必须总共上传的字节数。uploadStarted
- 如果上传尚未开始,则为null
。一旦开始,此属性将存储一个 UNIX 时间戳。请注意,这仅在预处理后设置。uploadComplete
- 表示上传是否完成的布尔值。注意,这并不意味着后处理也已完成。percentage
- 介于 0 和 100 之间的整数百分比。
file.size
file.size
文件大小,单位为字节。
file.isRemote
布尔值:此文件是否从远程提供商导入?
file.remote
用于远程提供商的数据包。通常对终端用户不太有趣。
file.preview
文件的可选视觉缩略图的 URL 。
file.uploadURL
上传完成后,这可能包含上传文件的 URL 。 根据服务器配置,它可能无法访问或不正确。
new Uppy(options?)
选项
id
实例在整个站点范围内的唯一 ID(string
,默认值:uppy
)。
如果使用了多个 Uppy 实例,例如,在两个不同的页面上,应指定一个
id
。这使得 Uppy 能够在不与其他 Uppy 实例冲突的情况下在localStorage
中存储信息 。
此 ID 应在页面重载和导航时保持持久性——不应该每次加载 Uppy 时都是一个随机数,每次都不相同。
autoProceed
一旦添加文件立即开始上传(boolean
,默认值:false
)。
默认情况下,Uppy 将在 UI 中按下上传按钮或调用 .upload()
方法后才开始上传。将此设置为 true
将在选择第一个文件后自动开始上传
allowMultipleUploadBatches
是否允许多个上传批次(boolean
,默认值:true
)。
这意味着多次调用 .upload()
,或者用户在已经上传一些之后添加更多文件的。一个上传批次由自上次调用 .upload()
以来添加的文件组成。
将此选项设置为 true
,用户可以上传一些文件,然后添加更多文件并同样上传。一个模型用例是将图片上传到画廊或向电子邮件添加附件。
将此选项设置为 false
,用户可以上传一些文件,并且您可以监听 'complete'
事件以继续应用程序的下一步上传流程。一个典型的用例是上传新的头像。如果您正在与现有 HTML 表单集成,此选项提供了最接近于裸露 <input type="file">
的行为 。
debug
是否发送调试和警告日志( boolean
,默认值: false
)。
将此设置为 true
会将 logger
设置为 debugLogger
。
logger
用于 uppy.log
的日志记录器( Object
,默认: justErrorsLogger
)。
通过提供您自己的logger
,您可以将调试信息发送到服务器,选择仅记录错误等。
将
logger
设置为debugLogger
以将调试信息输出到浏览器控制台:
您也可以提供自己的日志记录器对象:它应该公开
debug
、warn
和error
方法,如下面的例子所示。
这是一个什么都不做的logger
示例:
restrictions
限制上传的条件( Object
,默认值: {}
)。
属性 | 值 | 描述 |
---|---|---|
maxFileSize |
number |
每个单独文件的最大文件大小(字节) |
minFileSize |
number |
每个单独文件的最小文件大小(字节) |
maxTotalFileSize |
number |
所有可选上传文件的总最大文件大小(字节) |
maxNumberOfFiles |
number |
可以选择的文件总数 |
minNumberOfFiles |
number |
必须在上传前选择的文件最小数量 |
allowedFileTypes |
Array |
通配符 image/* ,或确切的 MIME 类型 image/jpeg ,或文件扩展名 .jpg :['image/*', '.jpg', '.jpeg', '.png', '.gif'] |
requiredMetaFields |
Array<string> |
要求每个文件的 meta 对象中的键在上传之前必须存在 |
NOTE
maxNumberOfFiles
也影响 UI 插件(如 DragDrop
、FileInput
和 Dashboard
)中的系统文件对话框中用户能够选择的文件数量。当设置为 1
时,他们只能选择一个文件。当设置为 null
或其他数字时,他们可以选择多个文件。
NOTE
allowedFileTypes
通过 <input>
接受属性传递给文件系统对话框,因此只有浏览器支持的类型才会工作。
TIP
如果你想在上传前强制输入特定的元数据字段,你可以 使用 onBeforeUpload
实现 。
TIP
如果您需要将 allowedFileTypes
限制为带有双点的文件扩展名,如 .nii.gz
,您可以 通过将 allowedFileTypes
设置为扩展名的最后一部分,allowedFileTypes: ['.gz']
,然后使用 onBeforeFileAdded
过滤 .nii.gz
。
meta
附加到每个文件元数据的键/值对 ( Object
,默认: {}
)。
还存在两个用于更新
metadata
的方法:setMeta
和setFileMeta
。
元数据也可以通过页面上的
<form>
元素、使用 Form 插件或在使用 Dashboard 及metaFields
选项时通过 UI 来添加。
onBeforeFileAdded(file, files)
在文件被添加到 Uppy 之前调用的函数( Function
,默认: (files, file) => !Object.hasOwn(files, file.id)
)。
使用此函数对所选文件进行任意数量的自定义检查,或对其进行操作,例如优化文件名。您也可以允许重复文件。
您可以返回 true
以保持文件不变,false
以移除文件,或返回修改后的文件。
警告
此方法仅用于快速同步检查和修改。如果您需要进行异步 API 调用,或对文件进行重工作(如压缩或加密),您应该改用 自定义插件 。
默认情况下,不会向用户显示关于文件未通过验证的通知。我们建议使用
uppy.info()
显示消息给用户,并通过uppy.log()
记录到控制台以供调试。
过滤、更改和中断示例
允许所有文件,包括重复文件。这将在文件未被上传时替换文件。如果再次上传重复文件,处理方式取决于您的上传插件和后端。
仅保留满足条件的文件:
更改所有文件名:
中断文件上传:
onBeforeUpload(files)
在上传开始前调用的函数(Function
,默认:(files) => files
)。
使用此函数检查所有文件或它们的总数是否符合您的要求,或在上传前一次性操纵所有文件。
您可以返回 true
继续上传,false
取消上传,或返回修改后的文件。
警告
此方法仅用于快速同步检查和修改。如果您需要进行异步 API 调用,或对文件进行重工作(如压缩或加密),您应该改用 自定义插件 。
默认情况下,不会向用户显示关于文件未通过验证的通知。我们建议使用
uppy.info()
显示消息给用户,并通过uppy.log()
记录到控制台以供调试。
更改和中断示例
更改所有文件名:
中断上传:
locale
您可以通过传递包含要覆盖键的 strings
对象来覆盖区域设置字符串。
NOTE
数组索引的对象用于复数化。
如果您需要其他语言,最好使用 地区设置 。
store
用于跟踪内部状态的存储 ( Object
,默认:DefaultStore
)。
此选项可用于将 Uppy 状态插入外部状态管理库,如 Redux 。
infoTimeout
Informer 通知可见的时间长度 (number
,默认:5000
) 。
方法
use(plugin, opts)
向 Uppy 添加插件,并可选地提供插件选项对象。
removePlugin(instance)
卸载并移除插件。
getPlugin(id)
通过其 id
获取插件以访问其方法。
getID()
获取 Uppy 实例 ID,请参阅 id
选项。
addFile(file)
将新文件添加到 Uppy 的内部状态。addFile
将返回添加的文件生成的 id。
如果文件无法添加,addFile
会给出错误,原因可能是 onBeforeFileAdded(file)
抛出了错误,或者 uppy.opts.restrictions
检查失败。
NOTE
如果你尝试添加一个已经存在的文件,addFile
将会抛出一个错误。除非该重复文件是通过文件夹拖拽时产生的——来自不同文件夹的重复文件在选择该文件夹时是允许的。这是因为我们向 file.id
中添加了 file.meta.relativePath
。
查看 如何处理 Uppy 文件 。
如果
uppy.opts.autoProceed === true
,当有文件被添加时,Uppy 将会自动开始上传。
有时你可能需要向 Uppy 中添加远程文件。这可以通过 获取文件然后创建 Blob 对象实现,或者使用 Url 插件配合 Companion来实现。
有时你可能需要标记某些文件为 “已上传”,以便用户看到它们,但实际上它们不会被 Uppy 再次上传。这可以通过 遍历文件并设置
uploadComplete: true, uploadStarted: true
在它们身上来实现 。
removeFile(fileID)
从 Uppy 中移除一个文件。移除正在上传的文件会取消那个上传过程。
clearUploadedFiles()
清除状态。在成功上传后手动重置 Uppy 时可能会用到。
上传插件可能会在上传过程中被调用时抛出错误。
getFile(fileID)
通过其 ID 获取特定的 Uppy 文件 。
getFiles()
获取所有已添加的 Uppy 文件 数组 。
upload()
开始上传已添加的文件。
返回一个 Promise result
,解析后包含两个数组,分别表示已上传的文件:
result.successful
- 成功上传的文件。result.failed
- 未成功上传的文件。这些文件将具有描述问题的.error
属性。
pauseResume(fileID)
在上传上切换暂停/恢复。仅当使用可恢复上传插件,如 Tus 时有效。
pauseAll()
暂停所有上传。仅当使用可恢复上传插件,如 Tus 时有效。
resumeAll()
恢复所有上传。仅当使用可恢复上传插件,如 Tus 时有效。
retryUpload(fileID)
重试一个上传(例如,在错误之后)。
retryAll()
重试所有上传(例如,在错误之后)。
cancelAll({ reason: 'user' })
参数 | 类型 | 描述 |
---|---|---|
reason |
string |
取消的原因。插件可以使用此来提供不同的清理行为(Transloadit 插件会在用户点击“取消”按钮时取消 Assembly)。可能的值有:user (默认)- 用户已按下 “取消” ;unmount - Uppy 实例已被程序关闭 |
取消所有上传,重置进度并移除所有文件。
setState(patch)
更新 Uppy 的内部状态。通常,这个方法在内部被调用,但在某些情况下,直接更改某些内容可能很有用,尤其是在实现自定义插件时。
Uppy 初始化时的默认状态:
更新状态:
NOTE
Uppy 中的状态被认为是不可变的。在更新值时,请确保不修改它们,而是创建副本。更多关于这一点的信息,可以参考 Redux 文档 。
getState()
返回来自 Store 的当前状态。
setFileState(fileID, state)
更新单个文件的状态。这对于可能希望在 Uppy 文件 上存储数据,或需要将文件特定配置传递给其他支持此功能的插件的插件特别有用。
fileID
是字符串形式的文件 ID。state
是一个对象,它将被合并到文件的状态对象中。
setMeta(data)
更改状态中的全局 meta
对象,该对象可以在 Uppy 选项中设置,并与所有新添加的文件合并。调用 setMeta
还会将新添加的元数据与之前选定的文件合并。
setFileMeta(fileID, data)
更新特定文件的元数据。
setOptions(opts)
更改 Uppy 初始化时使用的选项。
您也可以为插件更改选项:
close({ reason: 'user' })
参数 | 类型 | 描述 |
---|---|---|
reason |
string |
取消的原因。插件可以使用此来提供不同的清理行为(例如,Transloadit 插件在用户点击“取消”按钮时会取消 Assembly)。可能的值有:user (默认)- 用户已按下 “取消” ;unmount - Uppy 实例已被程序关闭 |
卸载所有插件并关闭此 Uppy 实例。在此之前也会运行 uppy.cancelAll()
。
logout()
对每个远程提供商插件(如 Google Drive、Instagram 等)调用 provider.logout()
。例如,在您的应用中用户注销账户后,这也将清理与 Uppy 云提供商的连接,以增强安全性。
log(message, type)
参数 | 类型 | 描述 |
---|---|---|
message |
string |
要记录的消息 |
type |
string? |
debug 、warn 或 error |
更多详情请参阅 logger 文档。
info(message, type, duration)
在状态中设置一个可由通知 UI 插件显示的消息,可选详细信息。它使用了默认包含在 Dashboard 中的 Informer 插件。
参数 | 类型 | 描述 |
---|---|---|
message |
string , Object |
'信息提示' 或 { message: '哦,不!', details: '文件无法上传' } |
type |
string? |
'info' 、'warning' 、'success' 或 'error' |
duration |
number? |
毫秒数 |
当此信息消息应显示或隐藏时,会触发 info-visible
和 info-hidden
事件。
addPreProcessor(fn)
添加一个预处理函数。fn
在上传开始前会接收到文件 ID 列表。fn
应该返回一个 Promise。其解析值将被忽略。
要更改文件数据等,请使用 Uppy 状态更新,例如使用
setFileState
。
addUploader(fn)
添加一个上传器函数。fn
在应该开始上传时会接收到文件 ID 列表。上传器函数应执行实际的上传工作,比如创建并发送 XMLHttpRequest 或调用某些上传服务 SDK。fn
应该返回一个 Promise,当所有文件都被上传完毕后,这个 Promise 会解析。
TIP
您可能选择在某些文件上传失败时仍解析 Promise。这样,对于成功上传的文件,任何后处理仍会运行,而上传失败的文件将在调用 retryAll
时重试。
addPostProcessor(fn)
添加一个后处理函数。fn
在上传完成后会接收到文件 ID 列表。fn
应该返回一个 Promise,当处理工作完成时解析。Promise 的值将被忽略。
例如,您可以等待文件编码或 CDN 传播完成,或者您可以进行 HTTP API 调用来创建一个包含所有已上传图像的相册。
removePreProcessor/removeUploader/removePostProcessor(fn)
移除处理器或上传器函数
从 Uppy 中移除之前添加的处理器或上传器功能。通常,这应该在 uninstall()
方法中完成。
on('event', action)
订阅 Uppy 事件。下面列出了所有事件的完整列表。
once('event', action)
创建一个只触发一次的事件监听器。下面列出了所有事件的完整列表。
off('event', action)
取消订阅 Uppy 事件。下面列出了所有事件的完整列表。
事件
Uppy 公开了一系列可以订阅以产生副作用的事件。
file-added
每当有文件被添加时触发。
参数
file
- 被添加的 Uppy 文件 。
files-added
参数
files
- 一次性添加(批处理)的 Uppy 文件 数组。
当有一个或多个文件被添加时触发——一个事件,代表所有文件。
file-removed
每当有文件被移除时触发。
参数
示例
upload
当上传开始时触发。
preprocess-progress
预处理器的进度。
参数
progress
是一个对象,具有以下属性:
mode
- 可能是'determinate'
或'indeterminate'
。message
- 显示给用户的提示信息。如'正在准备上传...'
,尽可能具体。
当 mode
是 'determinate'
时,还需添加 value
属性:
value
- 介于 0 和 1 之间的进度值。
progress
每次总上传进度更新时触发:
参数
progress
- 表示总上传进度的整数(0-100)。
示例
upload-progress
每当单个文件上传进度可用时触发:
参数
file
- 进度更新的 Uppy 文件 。progress
- 与file.progress
中相同的对象。
示例
postprocess-progress
后处理器的进度。
参数
progress
是一个对象,具有以下属性:
mode
- 可能是'determinate'
或'indeterminate'
。message
- 显示给用户的提示信息。如'正在准备上传...'
,尽可能具体。
当 mode
是 'determinate'
时,还需添加 value
属性:
value
- 介于 0 和 1 之间的进度值。
upload-success
每当单个上传完成时触发。
参数
file
- 被上传的 Uppy 文件 。response
- 包含来自远程端点的响应数据的对象。实际内容取决于所使用的上传插件 。
对于 @uppy/xhr-upload
,形状如下:
示例
complete
当所有上传完成时触发。
result
参数是一个对象,包含 successful
和 failed
文件数组,类似于 uppy.upload()
的返回值。
error
当 Uppy 无法上传或编码整个上传时触发。
参数
error
- 错误对象。
示例
upload-error
每次单个上传失败时触发。
参数
file
- 未上传成功的 Uppy 文件 。error
- 错误对象。response
- 可选参数,包含来自上传端点的响应数据。
根据使用的上传插件,它可能未定义或包含不同数据。
对于 @uppy/xhr-upload
,形状如下:
示例
如果错误与网络条件有关——例如,由于防火墙或 ISP 阻止导致端点不可达——错误对象将具有 error.isNetworkError
属性设置为 true
。检查网络错误的方法如下:
upload-retry
当上传被重试(例如,在错误之后)时触发。
此事件在用户尝试重新上传所有文件时不会触发,此时会触发 retry-all
事件。
参数
fileID
- 正在被重试的文件 ID。
示例
upload-stalled
当上传在一段时间内没有收到任何进度(在 @uppy/xhr-upload
中,延迟由 timeout
选项定义)时触发。使用此事件在 UI 上显示消息,告诉用户他们可能需要重试上传。
retry-all
当所有失败的上传被重试时触发。
参数
fileIDs
- 数组,包含被重试的文件 ID。
示例
info-visible
当 “info” 消息应显示在用户界面中时触发。默认情况下,Informer
插件会显示这些消息(在 Dashboard
插件中默认启用)。你可以利用此事件在自定义 UI 中显示消息:
info-hidden
当“info”消息应隐藏在用户界面中时触发。参见 info-visible
。
cancel-all
参数 | 类型 | 描述 |
---|---|---|
reason |
string |
参见 uppy.cancelAll |
当调用 cancelAll()
,所有上传被取消,文件被移除,进度被重置时触发。
restriction-failed
当添加的文件违反了某些限制时触发。此事件为希望自定义文件上传限制行为的人提供了另一种选择。
reset-progress
当调用resetProgress()
,每个文件的上传进度都被重置为零时触发。
new BasePlugin(uppy, options?)
构建插件的基础构造块。
BasePlugin
不包含 DOM 渲染,因此可用于没有用户界面的插件 。
有关于 Preact 渲染接口的扩展版本,请参见 UIPlugin 。
查看 构建插件 指南。
如果你不使用任何 UI 插件,并且想确保 Preact 没有被打包进你的应用中,可以这样导入 BasePlugin
:import BasePlugin from '@uppy/core/lib/BasePlugin
。
选项
传递给 BasePlugin
的选项是你希望在插件中支持的所有选项。
你应该在插件类的构造函数中将选项传递给 super
:
方法
setOptions(options)
初始化时传入的选项也可以通过 setOptions
动态更改。
getPluginState()
从 Uppy
类中检索插件状态。Uppy 在状态中保持一个 plugins
对象,其中每个键是插件的 id
,值是它的状态。
setPluginState()
在 Uppy
类中设置插件状态。Uppy 在状态中保持一个 plugins
对象,其中每个键是插件的 id
,值是它的状态。
install()
install
方法在插件使用 .use()
被添加到 Uppy 时运行一次。在此处初始化插件。
例如,如果你正在创建一个预处理器(如 @uppy/compressor ),你需要添加它:
另一个常见的做法是,当你创建一个 UI 插件 时,将其 挂载 到 DOM 上:
uninstall()
uninstall
方法在插件从 Uppy 中移除时运行一次。这发生在调用 .close()
或在框架集成中销毁插件时 。
在此清理事物。
例如,当你创建一个预处理器、上传器或后处理器时,要移除它:
卸载方法
i18nInit
在插件类的构造函数中调用 this.i18nInit()
一次,以初始化 国际化 。
addTarget
您可以使用此方法使您的插件成为其他插件的 target
。这是 @uppy/dashboard
用来向其用户界面添加其他插件的方式。
update
在每次状态更新时被调用。您很少需要使用这个,除非您想使用除 Preact 之外的其他工具来构建用户界面插件。
afterUpdate
在每次状态更新后带有防抖处理调用,此时所有内容都已挂载完毕。
new UIPlugin(uppy, options?)
UIPlugin
扩展了 BasePlugin
以添加使用 Preact 的渲染功能。当您想要创建用户界面或对其进行补充(如 Dashboard )时,请使用此方法。
参见
BasePlugin
了解所有插件的初始构建模块。
查看 构建插件 指南。
选项
传递给 UIPlugin
的选项是您希望在插件中支持的所有选项。
您应该在插件类中将这些选项传递给 super
:
反过来,这些也会传递给底层的 BasePlugin
。
方法
从 BasePlugin
继承的所有方法也进入了 UIPlugin
。
mount(target)
将此插件挂载到 target
元素上。target
可以是 CSS 查询选择器、DOM 元素或另一个插件。如果 target
是一个插件,源(当前)插件将在目标插件中注册,后者可以决定如何和在哪里渲染源插件。
onMount()
在 Preact 渲染完插件的组件后被调用。
unmount
从 DOM 中移除插件。通常您不需要覆盖它,但应从 uninstall
中调用它。
默认值是:
onUnmount()
在元素从 DOM 中移除后被调用。可用于清理或其他副作用。
render()
渲染插件的用户界面。Uppy 使用 Preact 作为其视图引擎,因此 render()
应返回一个 Preact 元素。render
会由 Uppy 在每次状态变化时自动调用。
update(state)
在每次状态更新时被调用。您很少需要使用这个,除非您想使用除 Preact 之外的其他工具来构建用户界面插件。
debugLogger()
开发期间提供额外调试和警告日志的记录器。
您也可以通过设置
debug
为true
来启用此记录器。
logger
的默认值是 justErrorsLogger
,看起来像这样:
debugLogger
发送额外的调试和警告日志,这在开发期间可能有帮助:
常见问题解答
如何允许重复文件?
您可以使用 onBeforeFileAdded
允许所有文件,甚至是重复文件。这将会覆盖尚未上传的文件。如果您再次上传重复文件,具体处理方式取决于您的上传插件和后端。