You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Strapi集成Contabo S3对象存储:URL格式不符的配置求助

问题描述

我正在用Strapi CMS的@strapi/provider-upload-aws-s3插件对接兼容S3的Contabo对象存储,目前上传、删除功能正常,但生成的文件URL格式不符合Strapi期望:

  • Strapi期望的URL格式:https://eu2.contabostorage.com/xxx-bucket/yyy.jpeg
  • Contabo实际返回的公开URL格式:https://eu2.contabostorage.com/zzz:xxx-bucket/yyy.jpeg

其中zzz疑似租户ID,但未确认。当前的Strapi上传配置如下:

upload: {
  config: {
    provider: "aws-s3",
    providerOptions: {
      credentials: {
        accessKeyId: env("CONTABO_OBJECT_STORAGE_ACCESS_KEY"),
        secretAccessKey: env("CONTABO_OBJECT_STORAGE_SECRET_KEY"),
      },
      endpoint: env("CONTABO_OBJECT_STORAGE_ENDPOINT"),
      forcePathStyle: true,
      region: "default",
      params: {
        Bucket: env("CONTABO_OBJECT_STORAGE_BUCKET"),
      },
    },
  },
},

解决方案

方案1:用Strapi生命周期钩子修正URL

在Strapi项目的src/api/upload/content-types/upload/lifecycles.js文件中添加钩子逻辑,在文件上传/更新后自动修正URL,去掉租户ID前缀:

module.exports = {
  async afterCreate(event) {
    const { result } = event;
    if (result.url && result.url.includes(':')) {
      // 从环境变量的桶名中提取不带租户ID的部分
      const bucketName = process.env.CONTABO_OBJECT_STORAGE_BUCKET.split(':')[1];
      // 替换URL中的"租户ID:桶名"为纯桶名
      const correctedUrl = result.url.replace(`${process.env.CONTABO_OBJECT_STORAGE_BUCKET}`, bucketName);
      // 更新数据库中存储的URL
      await strapi.db.query('plugin::upload.file').update({
        where: { id: result.id },
        data: { url: correctedUrl },
      });
    }
  },
  async afterUpdate(event) {
    const { result } = event;
    if (result.url && result.url.includes(':')) {
      const bucketName = process.env.CONTABO_OBJECT_STORAGE_BUCKET.split(':')[1];
      const correctedUrl = result.url.replace(`${process.env.CONTABO_OBJECT_STORAGE_BUCKET}`, bucketName);
      await strapi.db.query('plugin::upload.file').update({
        where: { id: result.id },
        data: { url: correctedUrl },
      });
    }
  },
};

注意:需要确保你的CONTABO_OBJECT_STORAGE_BUCKET环境变量是zzz:xxx-bucket格式,这样才能通过split提取到纯桶名。

方案2:修改AWS S3插件的URL生成逻辑

如果钩子方式不够灵活,可以把官方的@strapi/provider-upload-aws-s3插件代码复制到本地项目中,修改lib/upload.js里的URL生成方法:
找到原插件中类似这样的代码:

const getFileUrl = (file, config) => {
  const { endpoint, params } = config.providerOptions;
  return `${endpoint}/${params.Bucket}/${file.key}`;
};

修改为:

const getFileUrl = (file, config) => {
  const { endpoint, params } = config.providerOptions;
  // 去掉桶名里的租户ID前缀,若没有则直接用原桶名
  const bucketName = params.Bucket.split(':')[1] || params.Bucket;
  return `${endpoint}/${bucketName}/${file.key}`;
};

之后在Strapi的package.json中引用本地修改后的插件,替换原官方包。

方案3:绑定Contabo自定义域名(可选)

如果你的Contabo对象存储支持自定义域名,可以直接将域名绑定到目标桶,这样就能生成https://your-custom-domain/yyy.jpeg格式的URL,完全避开租户ID的路径问题。

内容的提问来源于stack exchange,提问作者yarex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:27:07