您可能已经注意到,在过去的几个月里,Discourse 核心中有许多与上传相关的提交。这是核心团队为在我们的代码库中替换 jQuery file upload 的用法而进行的整体工作的一部分,也是为了更广泛地替换代码库中 jQuery 的用法。jQuery 文件上传器是一个非常古老的项目,自 Discourse 核心诞生以来就一直存在。我想我在其他项目中的整个职业生涯中都使用过它。但现在是时候告别“老可靠”了:
我们已经用一个名为 Uppy 的库替换了 jQuery 文件上传器(并且很快也将替换另一个库 resumable.js)。这是一个更现代化的上传库,易于通过插件进行扩展,并且能够处理我们遇到的各种工作流程。重要的是,这使我们能够从 Discourse 客户端直接进行 multipart 上传到 S3,而无需将大文件通过我们的 API 发送。
现在,编辑器已将 Uppy 用于所有上传,并且应用程序中的许多其他地方也使用了它(头像上传、个人资料背景上传等)。在接下来的几周内,最后几个遗留部分也将被移除。这对大多数用户来说将是一个基本不可见的更改,但插件和主题组件的作者需要进行一些更改。
插件 API
预处理器
所有上传预处理器现在都需要作为 Uppy 插件 来编写。这些插件编写起来相当简单,并使用简单的基于 Promise 的工作流程。上传预处理器可以在 Uppy 将文件上传到 S3 或 /uploads.json 端点之前修改文件或为其添加元数据。我们已经在核心中设置了几个预处理器,您可以在编写自己的预处理器时参考它们:
- discourse/app/assets/javascripts/discourse/app/lib/uppy-checksum-plugin.js at 6662101208089def86ed18a81ac90d1c52670569 · discourse/discourse · GitHub
- discourse/app/assets/javascripts/discourse/app/lib/uppy-media-optimization-plugin.js at 6662101208089def86ed18a81ac90d1c52670569 · discourse/discourse · GitHub
作曲家的上传预处理器通过 api.addComposerUploadPreProcessor 使用插件 API 进行注册:
上传处理程序
上传处理程序 不 作为 Uppy 插件编写;它们仍然像以前一样工作,只是有一个小的更改。现在,当一个文件匹配到已注册到上传处理程序的扩展名时,所有匹配的文件将一次性发送。以前一次只有一个文件会被发送到上传处理程序,而现在发送的是一个数组:
由上传处理程序处理的文件将不会在 Uppy 上传管道中进一步处理。预处理器在调用上传处理程序之前运行。
S3 Multipart 直接上传
前面我提到,我们使用 Uppy 还可以让我们从 UI 进行直接的 multipart 上传到 S3。要启用此功能,您需要将 enable_direct_s3_uploads 站点设置设置为 true。
如果您托管在我们的平台上,相关的 S3 权限已应用于您的存储桶。但是,如果您是自托管的,则必须在存储桶上设置几个权限和 CORS 规则才能使其正常工作。
对于 CORS 规则,您只需要运行 s3:ensure_cors_rules rake 任务,命令为 rake s3:ensure_cors_rules。只要您为 Discourse 实例上的 S3 凭据设置了任何访问密钥和秘密密钥,它就会将以下规则添加到您的存储桶中。
{
"AllowedHeaders": [
"Authorization",
"Content-Disposition",
"Content-Type"
],
"AllowedMethods": [
"GET",
"HEAD",
"PUT"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"ETag"
],
"MaxAgeSeconds": 3000
}
对于权限,您需要为 Discourse 实例上的 S3 凭据设置的任何访问密钥和秘密密钥启用以下权限。
{
"Sid": "YourSid",
"Effect": "Allow",
"Action": [
"s3:PutObjectVersionAcl",
"s3:PutObjectAcl",
"s3:PutObject",
"s3:GetObjectAcl",
"s3:GetObject",
"s3:DeleteObject",
"s3:CreateMultipartUpload",
"s3:CompleteMultipartUpload",
"s3:AbortMultipartUpload"
],
"Resource": [
"YOUR_RESOURCE"
]
}
这项工作已经进行了好几个月,我们还没有完成!当我们将 jQuery 文件上传器和 resumable.js 完全从 Discourse 核心中移除时,我会在这个主题中发布通知。如果您对这里发布的内容有任何疑问,请告诉我!

