ToolJet 实战:用可视化组件在 AWS S3 上构建文件上传与下载应用
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
本指南基于 ToolJet 官方 How-To 文档(docs/versioned_docs/version-3.0.0-LTS/how-to/upload-files-aws.md)整理而成,完整演示如何不写一行后端代码,仅用 ToolJet 画布上的 Dropdown、Table、Text Input、File picker 与 Button 五个组件,配合四个查询,快速搭建一个可浏览、可上传、可生成签名下载链接的 AWS S3 文件管理界面。读完本文,你将掌握 S3 数据源接入、组件与查询之间的动态数据绑定({{queries...}}与{{components...}}表达式)以及文件二进制数据的 base64 上传链路,并理解其背后的插件级实现原理。
前置准备:为 ToolJet 接入 AWS S3 数据源
在开始搭建 UI 之前,必须先完成 AWS S3 数据源的配置。完整的接入说明见 S3 数据源文档,这里提炼关键信息:
- 入口:在查询面板点击+ Add new Data source按钮,或从 ToolJet 仪表盘进入Data Sources页面添加。
- 三种认证方式(对应插件源码 plugins/packages/s3/lib/index.ts 中的
getConnection实现):
| 认证方式 | 需要提供的参数 | 底层实现 |
|---|---|---|
| IAM Access Keys | Region、Access key、Secret key | 静态密钥直接构造S3Client |
| AWS Instance Credentials | 无需密钥(勾选后使用) | 通过fromInstanceMetadata从 EC2/ECS 元数据服务获取临时凭证 |
| AWS ARN Role | Region、Role ARN | 通过 STS 的AssumeRoleCommand换取临时凭证 |
官方建议为 ToolJet 创建一个独立的 IAM 用户,以便精确控制其访问级别,避免使用高权限的根账号密钥。
数据源添加完成后,在查询管理器底部面板点击+ Add,选择Amazon AWS S3数据源,再从操作下拉框选择所需操作并填写参数,即可通过Preview预览输出或Run触发查询。
搭建界面:五个组件各司其职
整个上传/下载界面的核心由以下组件构成,每个组件承担一个明确的职责:
| 组件 | 用途 |
|---|---|
| Dropdown | 用于选择 S3 存储桶 |
| Table | 列出 Dropdown 中选中桶内的所有对象 |
| Text Input | 获取待上传文件的目标路径 |
| File picker | 选择要上传的本地文件 |
| Button | 触发上传查询 |
配置查询:四个查询串联完整流程
我们总共会创建 4 个查询,它们共同覆盖「选桶 → 列对象 → 生成下载链接 → 上传文件」的完整闭环:
- getBuckets— 获取所有桶的列表
- listObjects— 列出选中桶内的对象
- uploadToS3— 将文件上传到指定桶
- download— 为指定对象生成签名下载 URL
getBuckets:拉取桶列表并填充下拉框
新建查询,选择 AWS S3 数据源,操作选择List buckets,将查询命名为getBuckets并保存:
接着编辑Dropdown组件的属性:
- Label:设置为
Bucket - Option values:设置为
{{queries.getBuckets.data.Buckets.map(bucket => bucket['Name'])}}—— 查询返回的数据是对象数组,因此需要用map提取出每个桶的Name字段 - Option label:同样设置为
{{queries.getBuckets.data.Buckets.map(bucket => bucket['Name'])}},使显示的标签与选项值一致
最后为 Dropdown 添加事件处理器:在On select(选项被选中)事件上触发Run Query,选择运行listObjects查询,实现「换桶即刷新列表」的联动效果。
listObjects:列出选中桶内的对象
新建查询,操作选择List objects in a bucket,在Bucket字段中输入{{components.dropdown1.value}}—— 该表达式会动态读取 Dropdown 当前选中的值,无需写死桶名。
然后编辑Table组件的属性:
- Table data:
{{queries.listObjects.data['Contents']}} - 添加列(Add Columns):
| 列名(Column Name) | 对应 Key |
|---|---|
| Key | Key |
| Last Modified | LastModified |
| Size | Size |
- 添加操作按钮(Action button):按钮文本设为Copy signed URL,为其On Click事件添加Copy to clipboard动作,文本字段填入
{{queries.download.data.url}}—— 这样点击按钮即可把下方将要创建的download查询生成的签名 URL 复制到剪贴板。
从插件实现看,
listObjects底层调用的是 AWS SDK 的ListObjectsV2Command(见 plugins/packages/s3/lib/operations.ts),查询参数会透传Prefix、MaxKeys、StartAfter(Offset)和ContinuationToken。其中MaxKeys默认值为1000(见 plugins/packages/s3/lib/operations.json 的defaults字段),当桶内对象超过限制时,返回结果中会携带Next Continuation Token,可用于分页拉取下一批对象。
download:为表格行生成签名下载 URL
新建查询,操作选择Signed URL for download:
- Bucket:
{{components.dropdown1.value}} - Key:
{{components.table1.selectedRow.Key}}—— 动态读取表格当前选中行的Key值
再回到Table组件的属性,为其添加事件处理器:在Row clicked(行点击)事件上运行download查询。这样每次点击表格中的某一行,就会为对应的对象生成一个签名 URL。
关于签名 URL 的时效性,插件实现中有明确的默认值:getSignedUrl(..., { expiresIn: options.expiresIn || 3600 })(见 operations.ts),即默认3600 秒(1 小时)过期;操作面板中的Expires in参数初始值也对应为3600。你可以按需调整该值,控制链接的有效期。
uploadToS3:上传文件到指定桶
新建查询,操作选择Upload object,在对应字段中填入以下绑定表达式:
| 字段 | 绑定表达式 | 说明 |
|---|---|---|
| Bucket | {{components.dropdown1.value}} | 上传到当前选中的桶 |
| Key | {{ components.textinput1.value + '/' +components.filepicker1.file[0].name}} | 由文本输入框的路径与文件原始文件名拼接出对象键 |
| Content type | {{components.filepicker1.file[0].type}} | 透传文件的 MIME 类型 |
| Upload data | {{components.filepicker1.file[0].base64Data}} | 文件的 base64 编码内容 |
| Encoding | base64 | 指定上传数据的编码方式 |
这些表达式所依赖的file[0].name、file[0].type、file[0].base64Data字段,正是 File picker 组件对外暴露的文件对象属性。查看前端实现 frontend/src/AppBuilder/Widgets/FilePicker/hooks/useFilePicker.js,可以看到组件在文件被选中后通过FileReader同时读取文本内容与 DataURL,再从中剥离出base64Data(readFileAsDataURLResult.split(',')[1]),连同name、type、size等元数据一起暴露给查询层使用。
而在插件侧,uploadObject的实现(operations.ts)会执行Buffer.from(data, encoding)将 base64 字符串还原为二进制内容,再通过PutObjectCommand连同ContentType一起写入 S3,这就是「Encoding 填base64」的原因——它告诉插件上传数据是 base64 编码,需要解码后再上传。
配置 File Picker 的接受类型与数量
点击组件手柄编辑 File picker 属性:
- Accept file types:设置为
{{"application/pdf"}}则只允许选择 PDF 文件;设置为{{"image/*"}}则只允许选择图片文件;若希望接受任意类型的文件,将该值留空即可。
文件类型必须是符合 input 元素规范的合法 [MIME 类型](如
application/pdf、image/png、text/plain等)或合法的文件扩展名。前端实现(useFilePicker.js)会把逗号分隔的类型字符串解析为 react-dropzone 的accept对象;当类型为空时accept置空,即不限制任何类型。
- Max file count:设置为
{{1}},因为本教程每次只上传 1 个文件(前端默认值为 2,单个文件大小上限默认 50 MB,见 useFilePicker.js,可按需调整)。
设置完成后,在 File picker 中选中一个 PDF 或图片文件并保持挂载状态。
上传成功后自动刷新列表
最后一步:打开uploadToS3查询的Advanced选项卡,添加一个在查询成功后运行的Run Query事件,目标为listObjects查询。这样每次文件上传完成后,表格都会自动重新拉取对象列表,立即展示新上传的文件。
源码视角:S3 插件的操作分发与连接逻辑
上述四个查询的操作,在插件源码中都有清晰对应(plugins/packages/s3/lib/operations.ts):
| 教程中的查询 | 界面上的操作 | 底层 AWS SDK 命令 |
|---|---|---|
| getBuckets | List buckets | ListBucketsCommand |
| listObjects | List objects in a bucket | ListObjectsV2Command |
| download | Signed URL for download | GetObjectCommand+getSignedUrl |
| uploadToS3 | Upload object | PutObjectCommand |
插件入口 plugins/packages/s3/lib/index.ts 的run方法会根据queryOptions.operation分发到对应实现,并统一把结果包装为{ status: 'ok', data: result }。值得注意的细节是allowDynamicConnectionParameters开关(默认开启):当它开启时,查询中的Bucket参数会覆盖数据源级的默认桶名(queryOptions.bucket || sourceOptions.bucket_name),这正是本教程允许每个查询通过{{components.dropdown1.value}}动态指定桶名的底层原因。
所有操作参数(字段标签、类型、占位符、初始值)都定义在 plugins/packages/s3/lib/operations.json 中,例如signed_url_for_get的expiresIn初始值为3600、upload_object的encoding占位符为utf8。如果你想了解插件的行为边界与测试方式,仓库还提供了测试脚手架 plugins/packages/s3/tests/s3.test.js。
总结
通过本教程,你已经在 ToolJet 中完成了一个完整的 AWS S3 文件管理应用:
- 浏览:Dropdown 绑定
getBuckets结果列出所有桶,Table 绑定listObjects结果展示对象列表; - 下载:Table 行点击触发
download查询生成签名 URL,行内按钮一键复制到剪贴板; - 上传:File picker 提供文件元数据与 base64 内容,
uploadToS3查询完成写入,上传成功后自动刷新列表。
整个过程中没有编写任何后端代码,全部依赖 ToolJet 的查询表达式与组件事件联动。掌握这套「数据源查询 + 组件动态绑定 + 事件链」的组合方式后,你可以举一反三:例如将Signed URL for upload操作与 File picker 配合实现直传、利用Prefix/Offset参数实现对象搜索与分页,或基于同样的模式把对象存储换成 GCS、MinIO 等兼容服务(ToolJet 同样支持通过自定义端点连接 S3 兼容存储)。对应的数据源参数与操作说明,可随时回到 S3 数据源文档 查阅。
【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 🚀项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考