内容本地化在翻译后的帖子中使用了原始 R2 存储桶 URL,而非 S3 CDN URL

你好,

在使用内容本地化(Content Localization)配合 Discourse AI 翻译以及将 Cloudflare R2 作为 S3 兼容存储时,翻译后的帖子内容存储的是原始的 R2 桶端点 URL,而不是配置的 s3_cdn_url(自定义域名)。这导致所有查看翻译内容的用户看到的图片均显示损坏。

环境配置

  • Discourse:最新版本
  • 通过 S3 兼容存储配置了 Cloudflare R2
  • s3_cdn_url: https://files.mydomain.com
  • s3_use_cdn_url_for_all_uploads: 已启用
  • Content Localization + Discourse AI 翻译:已启用

复现步骤

  1. 使用自定义域名(s3_cdn_url)配置 Cloudflare R2
  2. 启用 Content Localization 和 AI 翻译
  3. 创建一个包含图片的帖子
  4. 等待 AI 翻译生成本地化版本
  5. 切换语言——翻译版本中的图片显示损坏

观察到的行为

翻译后的内容中包含如下格式的 URL:

//files.myendpoint.r2.cloudflarestorage.com/original/1X/ 而非 https://files.mydomain.com/original/1X/

相关 Bug:Chat thumbnails bypass s3_cdn_url & use raw S3 bucket URLs

临时修复方案是执行重映射或使用以下主题组件(theme component):

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.8.0", (api) => {
  const badDomain = "files.myendpoint.r2.cloudflarestorage.com";
  const goodDomain = "files.mydomain.com";

  function fixImages() {
    document.querySelectorAll(`img[src*="${badDomain}"]`).forEach(img => {
      img.src = img.src.replace(badDomain, goodDomain);
    });
    document.querySelectorAll(`img[data-src*="${badDomain}"]`).forEach(img => {
      img.dataset.src = img.dataset.src.replace(badDomain, goodDomain);
    });
    document.querySelectorAll(`img[data-large-src*="${badDomain}"]`).forEach(img => {
      img.dataset.largeSrc = img.dataset.largeSrc.replace(badDomain, goodDomain);
    });
  }

  api.decorateCooked(() => fixImages(), { id: "fix-r2-translated-images" });
  api.onPageChange(() => fixImages());
});

我对这一点不太确定。我们的网站使用 Cloudflare R2 存储桶进行对象存储和备份,并且支持多种语言(通过 AI 翻译)。在所有语言版本中,图片都能正常加载。

例如:

英语

德语

俄语

葡萄牙语

是的,在我的测试中,我上传了 3 到 5 张图片。但只有 1 或 2 张按预期正常工作。