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

Next.js+Strapi环境下S3图片下载CORS问题求助

解决Next.js + Strapi从私有S3存储桶下载图片的CORS错误

1. 修正S3存储桶的CORS规则

私有S3桶的CORS配置不能仅依赖ExposeHeaders,必须完整配置允许的来源、方法和请求头,确保浏览器跨域请求被许可。以下是符合要求的配置示例:

[
  {
    "AllowedOrigins": ["https://你的Next.js生产域名", "http://localhost:3000"],
    "AllowedMethods": ["GET"],
    "AllowedHeaders": ["Authorization", "Content-Type"],
    "ExposeHeaders": ["Access-Control-Allow-Origin"],
    "MaxAgeSeconds": 3000
  }
]
  • AllowedOrigins严格指定你的前端域名,本地开发可加入localhost,生产环境务必删除;
  • AllowedMethods只保留需要的GET(下载图片用),避免过度开放;
  • AllowedHeaders必须包含Authorization,因为私有桶的预签名URL会携带签名参数,浏览器会校验这个头。

2. 确保Strapi生成S3预签名URL

私有存储桶的图片不能直接暴露原始对象地址,必须通过Strapi生成临时预签名URL,否则浏览器请求会因权限不足触发CORS。

  • 检查Strapi的AWS S3上传插件配置(@strapi/provider-upload-aws-s3),确保设置了private: true;
  • 确认AWS密钥、区域、桶名称等配置正确,Strapi能正常调用AWS SDK生成带有效期的预签名URL。

3. 前端代码的小优化

你的下载逻辑本身没问题,但要确保传入的imageUrl是Strapi返回的预签名URL,而非原始S3对象路径。可补充请求头明确接受图片类型,避免潜在的MIME类型问题:

export const downloadURI = async (imageUrl, name) => {
  try {
    const response = await fetch(imageUrl, {
      method: 'GET',
      headers: {
        'Accept': 'image/jpeg, image/png, image/gif'
      }
    });
    const blob = await response.blob();

    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = name;

    document.body.appendChild(a);
    a.click();

    window.URL.revokeObjectURL(url);
    document.body.removeChild(a);
  } catch (error) {
    console.error('图片下载失败:', error);
  }
};

4. 排查错误复现的根源

  • 打开浏览器开发者工具的Network面板,查看图片请求的响应头:
    • 确认Access-Control-Allow-Origin与你的前端域名完全匹配;
    • 检查请求URL是否为预签名格式(包含X-Amz-Signature等参数);
  • 如果之前修改ExposeHeaders后问题解决又复现,大概率是S3配置被意外重置,或Strapi的S3插件配置被修改导致不再生成预签名URL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:42:43