如何为你的应用添加文件上传:存储、限制与安全
要为应用添加文件上传,请把文件存储在对象存储(存储桶)中,而不是服务器磁盘或数据库里,并在数据库中保存一条小记录,包含文件的键、名称、大小、类型和所有者。在服务器端检查文件大小和类型,提前决定文件是公开的(如产品图片)还是私有的(如发票),并且只有在检查了请求者身份之后,才提供私有文件。在AI应用构建器中,你可以用一条提示词描述上传功能;关键在于测试文件在重新部署后是否仍然存在,以及错误的人是否无法打开它们。
先决定你需要哪种上传
在构建之前,先回答三个问题:
- 什么文件? 头像、产品图片、PDF、电子表格、音频、视频。这决定了类型和大小限制。
- 谁可以看到它们? 所有人(例如公开图库),还是只有上传者和管理员(合同、身份证件、客户文件)。
- 上传之后会发生什么? 只是存储,显示预览,压缩图片,还是读取其内容。
公开图片和私有文档需要不同的设置,因此要先把这一点确定下来。
文件应存放在哪里
| 选项 | 工作方式 | 适合 | 注意事项 |
|---|---|---|---|
| 对象存储(存储桶) | 文件存放在专门为此设计的服务中;你的数据库保存一个键或URL | 几乎所有应用 | 必须正确设置访问规则 |
| 平台提供的存储 | 你的应用构建器或托管平台为你启用一个存储桶 | 基于该平台构建的应用 | 限制和价格遵循该平台的规则 |
| 服务器磁盘 | 文件写入应用服务器的文件系统 | 仅用于本地开发 | 重启或重新部署后经常被清空 |
| 数据库中 | 把文件的字节存入表中 | 几乎从不推荐 | 会让数据库膨胀,拖慢备份 |
| 第三方上传组件 | 托管的上传服务处理整个流程 | 大型媒体、图片变换 | 另一个供应商、账户和账单 |
对于大多数应用,对象存储加上数据库记录才是正确的答案。数据库中的那一行是你的应用会查询的内容(“显示该用户的文档”);存储桶只负责保存字节内容。
公开文件与私有文件
- 公开文件(产品图片、博客图片、头像)可以通过公开URL提供。任何拥有链接的人都可以打开,对这类内容来说这没有问题。
- 私有文件(发票、合同、医疗或身份证件、客户交付物)绝不能有可被猜到的公开URL。服务器会检查登录用户是否拥有该文件或有权访问,然后要么把文件流式返回,要么返回一个签名URL:仅在短时间内有效的链接。
一个常见且严重的错误,是把私有文件存放在公开存储桶中,并使用可预测的文件名。任何人只要猜中 /uploads/invoice-102.pdf,就能看到别人的发票。
示例提示词
公开图片上传:
允许管理员为每个产品上传最多5张产品图片。每张接受JPG、PNG和WebP格式,最大5 MB。把文件存储在文件存储中,在 product_images 表中保存每个文件的键、大小和排序,并显示缩略图和删除按钮。在服务器端校验类型和大小,而不仅仅依赖浏览器。
私有文档上传:
为已登录的客户添加一个“文档”页面。客户可以上传最大20 MB的PDF。文件是私有的:存储在文件存储中,并在 documents 表中保存所有者ID、原始文件名、大小和上传时间,只有所有者和管理员可以下载。下载必须经过一个服务器路由,并检查权限。对这些文件绝不提供公开URL。
有用的后续要求:
上传期间显示进度条;如果文件过大或类型错误,显示清晰的错误提示。
删除文档记录时,同时删除已存储的文件。
分步操作
- 为每个上传字段确定类型和大小限制。 要具体:“最大20 MB的PDF”,而不是“文档”。
- 启用存储。 在AI构建器中,要求添加上传功能,它会为你完成存储设置;在其他平台上,请创建存储桶,并把其凭据添加为服务器端密钥。
- 为文件记录创建数据库表:ID、所有者、存储键、原始名称、类型、大小、创建时间。
- 在服务器上构建上传路由:检查用户是否已登录,检查类型和大小,生成安全的存储键(不使用用户的文件名),保存文件,插入记录。
- 构建下载或展示路径:公开文件使用公开URL;私有文件使用经过权限检查的路由或签名URL。
- 构建界面:文件选择器、必要时支持拖放、进度、预览和错误提示。
- 处理删除,确保删除记录的同时也删除已存储的文件。
- 测试:上传、刷新、重新部署或发布,并检查文件仍能加载。然后以另一个用户登录,尝试打开第一个用户的私有文件。
常见错误
- 把上传内容写入服务器磁盘。 在开发中可以正常运行,但重启或重新部署后文件就会消失。
- 相信浏览器端的检查。 文件输入框的“accept”设置只是提示,不是安全措施。请在服务器上检查类型和大小。
- 用用户的文件名作为存储键。 名称会冲突,还可能包含奇怪的字符。应生成唯一的键,并把原始名称单独存储。
- 用公开存储桶存放私有文件。 见上文;这是最容易上新闻的错误。
- 允许任何文件类型。 在某些配置下,从你的域名提供的HTML或SVG文件可能运行脚本。只接受你需要的类型。
- 没有大小限制。 一个超大的上传可能耗尽你的存储额度,或导致请求超时。
- 孤立文件。 删除了数据库记录却没有删除文件,会让你付费的存储空间慢慢被填满。
- 忘记移动端。 手机拍摄的照片可能很大,并且可能是HEIC等格式;请决定是接受还是转换。
检查清单
- 文件存放在对象存储中,而不是服务器磁盘或数据库里
- 每个文件都有一条包含所有者、键、名称、类型和大小的数据库记录
- 类型和大小在服务器端进行检查
- 存储键是生成的,而不是取自文件名
- 私有文件只有在通过权限检查之后才会提供
- 其他用户即使拿到链接也无法打开你的私有文件
- 删除记录时会删除文件
- 发布或重新部署之后文件仍能正常加载
- 上传错误会清晰地显示,包括在手机上
在Mythex中使用文件上传
当你的应用需要上传功能时,Mythex可以自动为项目启用文件存储,因此你无需手动配置存储桶。你也可以在聊天中输入 /storage。它在Free和Pro套餐中均可使用,Free套餐上限为1 GB,你可以在Settings → Storage中查看其状态。
文档明确指出,已发布的托管环境并非持久的本地文件系统,因此应要求代理使用平台存储,而不是保存到磁盘。存储文件和下载所产生的费用,将按大小和下载量从你的积分余额中扣除;Pro套餐的费率为Free套餐的一半。参见文档中的文件存储。
文件上传通常与用于保存文件记录的数据库,以及用于保护私有文件的登录功能配合使用。如果你要构建一个客户交换文件的平台,请参见如何构建客户门户,并在上线前完成AI构建应用安全检查清单中的各项检查。
常见问题
上传的文件应存放在哪里?
存放在对象存储中(专门存放文件的服务,通常称为存储桶),而不是应用服务器的磁盘上,也不是数据库里。在数据库中只需保存文件的键或URL,以及名称、大小和所有者等详细信息。
为什么我发布或重新部署之后,上传的文件消失了?
大多数托管平台不会保留持久的本地磁盘:应用重启或重新部署时,写入其磁盘的文件都会丢失。请把上传内容保存到对象存储中。
如何让上传的文件保持私密?
不要让文件可以被公开读取。由服务器检查当前登录用户是否有权查看某个文件,然后发送该文件,或返回一个短期有效的签名链接。
Mythex支持文件上传吗?
支持。当应用需要上传功能时,Mythex可以为项目启用文件存储,Free和Pro套餐均可使用,Free套餐的上限为1 GB。你可以请代理添加上传功能,或输入 /storage。