iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0

今日目標說明

昨天我們把上傳的圖片暫存在伺服器的記憶體中了。一般來說,我們會把圖片上傳到 AWS S3 或是 Imgur 這類圖床。但在我們這個小巧的 Side Project 中,為了減少串接外部服務的麻煩,我們決定將圖片轉換為 Base64 字串,直接存進 Turso 資料庫中!

【架構決策對比】圖片儲存策略大PK

把圖片直接塞進資料庫聽起來很瘋狂?讓我們來分析一下這個策略:

儲存策略 優點 缺點與限制 本系統的適用性
存成 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 上傳測試:在 Postman 中,將 Body 格式選為 form-data。新增一個 icon 欄位 (Type 選擇 File),選取一張小圖示送出。截圖回傳成功的畫面。

圖片以Base64字串存入資料庫

於資料庫可以看到圖片以Base64字串存在資料庫。

小結

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


上一篇
DAY 13:處理上傳檔案的利器 Multer (Serverless 儲存限制)
系列文
就決定是你了!打造寶可夢持有追蹤系統 (React x Express)14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言