报错是这么冒出来的。把图片整体搬到对象存储并绑定 img.example.com,站点 HTML 里的地址已经换好。图片搜索收录两周内从 1.8 万掉到 900,日志里对 /uploads/ 的请求全是 403 AccessDenied。
中间走过弯路,把「防盗链开了 Referer 白名单,蜘蛛的 Referer 为空被拒」当成主因,改完现象没变。
把日志和配置对完,能解释这个现象的基本就这几处。对象存储默认禁止 ListBucket,目录式地址直接返回 403。少数情况下是旧路径没有做重定向,HTML 之外的外链仍指向源站目录。
不容易想到的是,存储桶开启了静态网站托管 目录地址返回索引页而不是 403。
动手时先验证对象地址的返回码
curl -sI https://img.example.com/uploads/2020/a.jpg | head -4
给存量的目录请求做前缀重写
location /uploads/ { rewrite ^/uploads/(.*)$ https://img.example.com/uploads/$1 permanent; }
防盗链放行空 Referer
set $ok 0; if ($http_referer ~ 'example\.com') { set $ok 1; }
末了重新抽查图片抓取
curl -s -o /dev/null -w '%{http_code} %{content_type}\n' https://img.example.com/uploads/2020/a.jpg
恢复的判定其实很直接。补上重写与 Referer 放行后,图片请求的 403 占比从 78% 降到 2%,四十五天后图片搜索收录恢复到迁移前的六成。
这里还有个坑。对象存储的权限模型和文件系统不一样,目录地址天然不可访问,迁移前要把所有以目录形式出现的链接列出来逐条替换。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。
