我們的系統有一個進階功能:使用者可以自訂「標籤 (Tags)」,並且為每個標籤上傳一張可愛的小圖示 (Icon)。
處理上傳檔案跟處理 JSON 完全是兩碼子事!我們需要一套專門解析 multipart/form-data 的套件:Multer。同時,我們將面臨部署到 Serverless 雲端環境時的硬碟限制問題。
通常我們用 Multer 時,會把它設定為 DiskStorage,直接把圖片存進硬碟裡的 uploads/ 資料夾。但這在 Vercel 這種 Serverless 平台上是行不通的!
| 儲存策略 | 運作原理 | 在 Vercel (Serverless) 上的後果 |
|---|---|---|
DiskStorage (寫入硬碟) |
將接收到的檔案直接存入伺服器本機的硬碟中。 | 致命錯誤! Vercel 的檔案系統是「唯讀 (Read-only)」的。即使成功寫入 /tmp 暫存區,只要 API 執行結束,機器被回收,圖片就會立刻蒸發。 |
MemoryStorage (寫入記憶體) |
將接收到的檔案轉成 Buffer 格式,暫存在伺服器的 RAM (記憶體) 中。 | 本專案採用! 檔案不會碰到硬碟,我們會在記憶體中拿到檔案內容後,立刻轉存到資料庫或第三方圖床。 |
我們建立 src/middleware/upload.ts 來設定 Multer:
import multer from 'multer';
// 我們設定為記憶體儲存,完美避開 Vercel 的硬碟限制
const storage = multer.memoryStorage();
export const upload = multer({
storage: storage,
limits: {
fileSize: 200 * 1024 // 安全考量:限制圖示最大只能 200KB
},
fileFilter: (req, file, cb) => {
// 只允許上傳圖片格式
if (file.mimetype.startsWith('image/')) {
cb(null, true);
} else {
cb(new Error('只允許上傳圖片檔'));
}
}
});
現在,當我們在 API 中使用 upload.single('icon') 時,上傳的圖片就會被轉化為二進位資料 (Buffer),安穩地躺在 req.file.buffer 裡面等我們處理了!

精巧的 Multer 設定檔,特別標記
multer.memoryStorage(),幫助新手避開 Serverless 的硬碟限制。
我們成功在記憶體中接住了使用者的圖片!但這張圖片現在還只是記憶體中的一段二進位亂碼,明天,我們就要將它轉化為 Base64 格式,永久封存在我們的資料庫中!