媒体同步到S3后后台能看到缩略图,前台原图却403。先分清前台URL是公开对象、CloudFront私有分发还是应用签名URL;Bucket私有时仅把文件上传成功还不够。

排查记录

我保留了一个失败样本,并用同样输入在无缓存或单节点条件下再跑一遍。这样可以把前端假象、缓存和真正的数据问题分开。

我先看了这几处

  • 复制前台最终图片URL看响应头中的Server和x-cache,确认403来自S3还是CDN。
  • 检查对象key大小写、Content-Type及CloudFront origin access配置。
curl -I "https://media.example.com/catalog/product/a/b/example.jpg"
aws s3api head-object --bucket shop-media --key catalog/product/a/b/example.jpg
bin/magento remote-storage:sync
bin/magento config:show system/media_storage_configuration/media_database

日志取样要带上请求时间、Store View、实体ID和部署版本。只截一行异常往往不够,至少保留错误前后几十行,才能判断是入口参数还是后续状态被改写。

处理办法

推荐保持Bucket私有,通过CloudFront OAC/OAI授予读取,并让Magento base media URL指向分发域名。Bucket Policy只授权该分发,不要开放Principal:*。若使用签名URL,确认缓存TTL短于签名有效期且查询参数未被代理删除。同步后做一次指定对象head检查。

修改范围

  • 先在单个SKU、单个订单或单个Store验证。
  • 保留可回退的旧配置,不覆盖原始证据。
  • 需要批量处理时分批提交并输出成功/失败清单。

回归时别只刷新页面

  • 匿名访问CDN URL为200
  • 直接S3私有URL仍被拒绝
  • 新上传与历史图片都可读
  • 缓存失效后不会间歇403

验收不只看后台提示“成功”。我还会从前台/API再走一次真实链路,并在下一轮cron、索引或缓存命中后重复检查,确认不是短暂正常。

补记

为省事打开整个Bucket公读会暴露未发布媒体和其他对象。