昨天我們把上傳的圖片暫存在伺服器的記憶體中了。一般來說,我們會把圖片上傳到 AWS S3 或是 Imgur 這類圖床。但在我們這個小巧的 Side Project 中,為了減少串接外部服務的麻煩,我們決定將圖片轉換為 Base64 字串,直接存進 Turso 資料庫中!
把圖片直接塞進資料庫聽起來很瘋狂?讓我們來分析一下這個策略:
| 儲存策略 | 優點 | 缺點與限制 | 本系統的適用性 |
|---|---|---|---|
| 存成 Base64 進資料庫 | 極致簡單。不需要申請 AWS S3,不需要處理圖床的金鑰,備份資料庫時圖片也會一起被備份。 | Base64 編碼會讓檔案體積 膨脹約 33%,大量存大圖會導致資料庫肥大,拖慢查詢速度。 | 非常適合! 我們的標籤圖示 (Icon) 只有限制 200KB,數量也少,塞進 DB 造成的負擔微乎其微。 |
| 上傳至專業圖床 (如 S3) | 不佔用資料庫空間,圖床有 CDN 網路加速,圖片載入超快。 | 開發成本高,需要額外管理外部服務,且有流量與儲存計費考量。 | 若未來開放上傳「高清寶可夢實體照片」,就必須改用此方案。 |
在 src/routes/tags.ts 中,我們將 Multer 接到的圖片轉成 Base64 並存入 DB:
import { upload } from '../middleware/upload';
// 使用 upload.single('icon') 中介軟體接住名為 icon 的檔案
router.post('/:tagId/icon', upload.single('icon'), async (req, res) => {
if (!req.file) return res.status(400).json({ error: '沒有上傳檔案' });
// 1. 將 Buffer 轉換為 Base64 字串
const base64Data = req.file.buffer.toString('base64');
// 2. 加上 Data URI 前綴,讓前端可以直接放進 <img src="..."> 裡面
const mimeType = req.file.mimetype;
const iconBase64 = `data:${mimeType};base64,${base64Data}`;
// 3. 直接 UPDATE 進標籤資料表
await db.execute({
sql: 'UPDATE tag_definitions SET icon_base64 = ? WHERE tag_id = ?',
args: [iconBase64, req.params.tagId]
});
res.json({ message: '圖示上傳並轉換 Base64 成功!' });
});
前端只要拿到這串字,直接寫 <img src={iconBase64} />,圖片就會神奇地跑出來啦!

Postman 上傳測試:在 Postman 中,將 Body 格式選為
form-data。新增一個icon欄位 (Type 選擇 File),選取一張小圖示送出。截圖回傳成功的畫面。

於資料庫可以看到圖片以Base64字串存在資料庫。
我們巧妙地利用 Base64 解決了 Serverless 環境的圖片儲存痛點!至此,「階段二:後端實作」的所有核心功能都已經打通。明天開始,我們要切換戰場,進入「階段三」,用 React 與 Material UI 把這個後端心血變成超美的網頁畫面!