核心痛點
- 使用者上傳圖片後未送出表單,導致孤立檔案佔用儲存空間。
- 前端即時上傳與後端資料關聯困難(圖片 ID 與文章 ID 綁定)。
標準解決流程
- 上傳至臨時目錄:
/tmp/uploads/{sessionId}/ 或 /var/www/temp/,檔名加上 UUID 避免衝突。
- 前端回傳暫存檔資訊:上傳成功後回傳
{tempId, originalName, path},前端暫存於表單隱藏欄位。
- 使用者送出表單:將暫存檔 ID 陣列隨表單提交。
- 後端原子化移動:收到請求後,將暫存檔移至正式目錄
/data/uploads/{articleId}/,寫入資料庫關聯,失敗則回滾。
- 定時清理任務:每小時掃描臨時目錄,刪除建立超過 1 小時且未關聯的檔案(或記錄於資料表由排程清理)。
資料庫設計建議
CREATE TABLE uploads (
id BIGINT PRIMARY KEY,
temp_path VARCHAR(512),
final_path VARCHAR(512),
status ENUM('TEMP','COMMITTED','DELETED') DEFAULT 'TEMP',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
article_id BIGINT NULL
);
前端體驗優化
- 顯示上傳進度條、縮圖預覽、刪除暫存按鈕。
- 離開頁面前提醒「有未提交的圖片,確定離開?」(
beforeunload)。
安全考量
- 驗證 MIME 型別、副檔名、檔案大小、圖片魔數。
- 儲存路徑不可直接對外公開,需經由權限檢查的下載/預覽 API。
- 定期掃描惡意腳本(ClamAV、自訂規則)。