Discourse 的文件上传新时代

您可能已经注意到,在过去的几个月里,Discourse 核心中有许多与上传相关的提交。这是核心团队为在我们的代码库中替换 jQuery file upload 的用法而进行的整体工作的一部分,也是为了更广泛地替换代码库中 jQuery 的用法。jQuery 文件上传器是一个非常古老的项目,自 Discourse 核心诞生以来就一直存在。我想我在其他项目中的整个职业生涯中都使用过它。但现在是时候告别“老可靠”了:

我们已经用一个名为 Uppy 的库替换了 jQuery 文件上传器(并且很快也将替换另一个库 resumable.js)。这是一个更现代化的上传库,易于通过插件进行扩展,并且能够处理我们遇到的各种工作流程。重要的是,这使我们能够从 Discourse 客户端直接进行 multipart 上传到 S3,而无需将大文件通过我们的 API 发送。

现在,编辑器已将 Uppy 用于所有上传,并且应用程序中的许多其他地方也使用了它(头像上传、个人资料背景上传等)。在接下来的几周内,最后几个遗留部分也将被移除。这对大多数用户来说将是一个基本不可见的更改,但插件和主题组件的作者需要进行一些更改。

插件 API

预处理器

所有上传预处理器现在都需要作为 Uppy 插件 来编写。这些插件编写起来相当简单,并使用简单的基于 Promise 的工作流程。上传预处理器可以在 Uppy 将文件上传到 S3 或 /uploads.json 端点之前修改文件或为其添加元数据。我们已经在核心中设置了几个预处理器,您可以在编写自己的预处理器时参考它们:

作曲家的上传预处理器通过 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 核心中移除时,我会在这个主题中发布通知。如果您对这里发布的内容有任何疑问,请告诉我!

49 个赞

5 个帖子已拆分为新主题:Uppy 在 Firefox 68 上不起作用

itsgoneitsdone

通过这两次提交,jQuery 文件上传器和 resumable.js 不再是 Discourse 核心的一部分:

我已经尽力将我们所知道的所有插件中对此以及我们旧的 UploadMixin 的引用全部移除,但可能还有一些我遗漏的或不知道的。别担心,迁移过程很简单。99% 的用例只需将我们的新 UppyUploadMixin 作为直接替换即可,只需极少的更改。例如,请看这里:

对于另外 1% 的情况,您可以创建 Uppy 的实例并直接挂接到事件。例如,请看这里:

我还将在该主题的 OP 中涵盖插件的更改。距离我们下一次发布还有几周时间,所以如果有人遇到任何问题,请在此处报告。这真是一段疯狂的旅程!:roller_coaster:

14 个赞

另外,API 文档已更新,增加了新的上传端点。请访问 Discourse API Docs 查看。

(抄送 @mattdm,您可能对此感兴趣)

6 个赞

启用直接 S3 上传后,我们收到来自中国用户的报告,称他们无法上传图片——图片卡在 0% 并超时。

第一反应可能是 S3 在中国被屏蔽了,但我们确切地知道并非如此——至少不是完全屏蔽:在中国,我们的用户可以正常查看存储在 S3 中的图片(在我们的例子中,存储桶位于 eu-central-1 区域)。但是,不知何故,似乎只有上传无法正常工作。

在防火长城(GFW)之外很难调试这个问题,但我们的一些中国用户提到,一个可能相关的区别是,图片是通过 双栈端点 加载的,但上传使用的是常规(仅 IPv4)端点(bucket-name.s3.dualstack.eu-central-1.amazonaws.combucket-name.s3.eu-central-1.amazonaws.com)。通过一些测试,我们确实发现情况似乎是这样,但不确定这是否是预期的或上传所必需的。

也许更说明问题的是,一些用户报告说,通过将双栈主机名解析出的 IP 添加到他们的 hosts 文件中(针对非双栈主机名),可以完全解决问题,并且仅通过这一更改他们就能成功上传。

不确定 Discourse 团队是否有人在中国,可以帮助更好地调试这个问题?

4 个赞

帖子已拆分为新主题:配置 S3 时出错:操作不存在