管理后台能列出「季度报告.pdf」,点下载返回 404,错误码是 NoSuchKey。把地址里的 %25E5 手动改成 %E5 就能下载。第一次遇到会往复杂处想,其实漏掉的多是个小前提。

python -c "from urllib.parse import quote; print(quote('季度报告.pdf'))"
aws s3api head-object --bucket b --key "季度报告.pdf"

生成签名时对 key 做过一次 URL 编码,拼链接时又编了一次,% 变成 %25。服务端只解码一次,拿到的是编码后的字符串,和真实 key 对不上。列表接口返回的是解码后的名字,两处才显得诡异。这一点先确认清楚,后面就不用反复试。

「对象 key 双重编码」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

具体做法是,key 只在拼 URL 时编码一次 其他环节保持原样;用 SDK 的生成方法 不要手工拼字符串;下载前打印最终 URL 和真实 key 比对;历史链接不兼容 直接重新生成。

改完照着核一遍,下载链接返回 200,Content-Disposition 里的文件名和列表显示一致。

作者 9823189