一句話:PUT 的語意是「把這個 key 的內容設成我傳的東西」——如果那個 key 已經有物件,就直接覆寫,不警告、不詢問。
S3 的每個物件由 key(路徑 + 檔名,例如 uploads/photo.jpg)唯一標識。對同一個 key 做 PUT,就是把它的內容整個換掉——這是 PUT 的正常語意,不是 bug。
如果你簽 presigned PUT URL 時,key 用的是「使用者可控 / 可預測」的值(例如直接照抄使用者上傳的原始檔名),就可能出事:
photo.jpg → 後者默默蓋掉前者,前者的檔案就沒了。
簽 presigned PUT 時,key 用後端產生的唯一值(UUID、內容雜湊、或 使用者ID/時間戳/隨機字串),不要照抄使用者給的檔名。原始檔名想保留就存進 metadata 或 DB,別拿來當 key。
// 壞:容易撞名覆蓋
key = userProvidedFileName; // "photo.jpg"
// 好:後端產唯一 key
key = $"uploads/{Guid.NewGuid()}.jpg"; // "uploads/6f9c...e2.jpg"
這樣天然避免撞名,也順帶讓 key 不可預測,安全性更好。