您好,
自上次更新以来(我们使用的是托管环境),我们的上传功能似乎已损坏,但我们并没有进行任何特殊操作。
我们只是在主题组件内注册了一个新的 api.addComposerUploadHandler()。
这以前可以很好地处理拖放到组合框中的多个文件。现在,控制台中会抛出似乎与 Uppy(我们不想要它)相关的错误。
我们的代码非常简单,但 Uppy 似乎干扰了它。
// 为视频注册自定义上传处理程序。
api.addComposerUploadHandler(["mp4", "mov", "mkv", "avi", "m4v"], (file, editor) => {
console.log("正在处理上传:", file.name);
})
将 3 个文件(mkv、mov、mkv)拖放到组合框会显示“您的文件大于 4 MB”的错误消息,而我们最初希望绕过此消息,因为我们将所有内容上传到 Gdrive。
Chrome 控制台抛出这些:
拖放一个 50MB 的单个文件不会导致“文件太大”的错误,并且我们的文件会按预期正确处理。因此,错误似乎发生在多个文件和单个大于 4MB 文件限制的文件上(我不确定这是在哪里设置的)。
感谢您的任何帮助。我认为这与 Discourse 本身的上次更新有关。
@martin
martin
(Martin Brennan)
2
您好 @Sören_Geier。最近这个区域有一些改动,尽管我曾试图与编辑器中现有的上传处理程序保持一致。我只是想更好地了解您的用例。据我所知,即使是编辑器的非 uppy 版本,通过 api.addComposerUploadHandler 上传也一次只能处理一个文件:
https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/mixins/composer-upload.js#L215-L222
所以,如果您拖放多个文件,就会发生正常流程,我想在本主题 OP 的情况下,您只是遇到了正常上传流程的文件大小限制。
当您一次拖放多个文件时,以前发生了什么,或者您期望发生什么?如果您不方便公开分享您的主题组件代码,请在此处通过私信与我分享。
所以只是确认一下,您是由我们托管的吗?
2 个赞
感谢 @martin 的快速回复。
是的,我们是和你们一起托管的。所以,当你把一个文件拖到编辑器里时,通常会发生什么呢?它会在编辑器里插入一些文字,比如“正在处理 <文件名>”……另外,在使用 API.addComposerUploadHandler([“mp4”, “mov”, “mkv”, “avi”, “m4v”]) 的情况下,这是 Discourse 在将文件交给这里的自定义处理程序之前完成的。那个占位符文本插入在某个时候停止工作了,那时我自己在处理程序中插入了代码:
composerController.model.appEvents.trigger("composer:insert-block", `[正在处理: ${file.name}...]()`);
接下来出问题的是,我们的处理程序没有启动,因为突然间那些视频扩展名从“主题授权扩展名”设置中消失了——或者我必须在其中重新添加它们才能让事情再次开始工作。
然后我发现了前面描述的“多个”文件拖放问题。
我们曾经让它在某种程度上起作用,我可以拖放 2 个或更多文件而没有出现错误消息。而且感觉也正确,因为我们绕过了所有 Discourse 的验证逻辑。
以下是相关的代码片段:
这里我只是期望 Discourse 将拖放的文件交给我。一个接一个。
// 注册视频的自定义上传处理程序。
api.addComposerUploadHandler(["mp4", "mov", "mkv", "avi", "m4v"], (file, editor) => {
console.log("正在处理上传:", file.name);
sendToGDrive(file, api);
})
因为 Discourse 将文件一个一个地交给我们,所以我创建了一个中间函数,它只是填充一个数组,然后在超时后启动实际的上传函数。所以我在收集 Discourse 传递过来的文件到我自己的数组中。
// 按顺序收集所有拖放的文件 - 由 Discourse 处理程序报告。
function sendToGDrive(file, api) {
clearTimeout(uploaderStartTimeout);
filesHolder.push(file)
const composerController = api.container.lookup("controller:composer");
composerController.model.appEvents.trigger("composer:insert-block", `[正在处理: ${file.name}...]()`);
uploaderStartTimeout = setTimeout(function () {
initFileSend(api);
}, 300);
}
然后我将每个文件单独上传到 Gdrive。
// 单独处理每个文件。
async function initFileSend(api) {
for (const file of filesHolder) {
const content = await sendFileToGdrive(file, api, uploadFolderId);
}
}
观察到的问题:
- “多个文件”拖放会导致文件大小验证,而单个文件拖放则不会。
1 个赞
martin
(Martin Brennan)
5
感谢您提供这份详细的报告和相关的代码。我之前在上传处理程序方面也有类似的思路;允许每个匹配处理程序的文件进入某种队列或池,就像您在这里所做的那样,然后一次性上传它们或将它们传递给其他用户界面,因为我确实觉得一次一个文件的限制很奇怪。不过,根据您所说的,也许我误解了旧的作曲家上传处理程序中一次一个文件的限制是如何工作的。
我将进行一些本地测试,看看旧的非uppy上传程序通过主题组件中您提供的函数的简化版本处理多个文件时是如何工作的,然后尝试在新旧方法之间实现对等,因为这比只允许一次一个文件要灵活得多。
这可能需要一些时间来修复,我今天会处理。
2 个赞
martin
(Martin Brennan)
6
我想快速同步一下信息;我确认了使用 pre-uppy composer 上传处理程序,虽然代码会检查是否只上传了一个文件,但这并不准确,因为 jQuery 文件上传程序一次只通过此代码路径发送一个文件,即使您一次性拖放了多个文件。这与 uppy 不同,uppy 会将添加的文件分组处理。我们创建的另外两个利用 api.addComposerUploadHandler 的插件也做了这种一次只处理一个文件的假设,所以这似乎是一个普遍存在的问题。
正如我所说,我认为最好的前进方向是允许此处理程序处理多个文件,然后可以将这些文件批量处理并以插件/主题作者认为合理的方式发送到其他地方。至少我可以修复 uppy 上传处理程序一次只能发送一个文件的假设。一旦有进一步更新,我将在此处再次发布。
2 个赞
martin
(Martin Brennan)
7
在周末前进行最后一次更新。我有一个修复程序,应该会在下周初合并,它将在 uppy 内部恢复 pre-uppy 的“旧”工作方式。因此,在此之后,您的实现将恢复正常工作:
但是,我也会添加一个后续的 PR,将 addComposerUploadHandler 更改为将 多个 文件通过数组的形式发送到处理程序回调,这样您就不需要设置队列和 setTimeout 回调来处理传入的多个文件了。我认为这无论如何都是更正确的,并且是对 API 的整体改进。
因此,您的处理程序届时将变成如下所示:
// 注册视频的自定义上传处理程序。
api.addComposerUploadHandler(
["mp4", "mov", "mkv", "avi", "m4v"],
(files, editor) => {
console.log("Handling upload for", files.map((file) => file.name).join(", "));
sendToGDrive(files, api);
}
);
2 个赞
太好了。感谢您如此迅速地对此进行调查!
祝您周末愉快,实至名归 
2 个赞
martin
(Martin Brennan)
9
3 个赞
martin
(Martin Brennan)
11
您使用的是我们的标准托管服务吗?如果是,现在应该已经部署了 
3 个赞
好的,我收到反馈说用户上传文件时遇到了问题。
我查看了一下,一开始在将文件对象传递给 GDRIVE 时也遇到了问题。结果发现文件对象是 uppy 包装过的二进制文件表示,看起来像这样。
为了实际访问原生文件对象,我不得不使用 files[0].data。(这可能是一个破坏性更改?)
在此更改之前,处理程序只是传递了原生文件对象。我不确定其他人是否也会因为这个更改而遇到功能中断的问题。
现在一切都已正常工作。非常感谢您的快速响应和支持!
3 个赞
martin
(Martin Brennan)
13
哎呀,你说得对,我真不知道上次重构时怎么会忽略了这一点!
我今天早上会推送一个修复补丁,很快就好。
编辑:修复补丁在这里,预计在未来几个小时内部署到我们的标准托管环境。
3 个赞
好的,我们也调整了代码。我认为现在可以关闭这个话题了。非常感谢 @martin 的出色帮助。
1 个赞