req.body)。但是,當前端需要上傳「檔案 (圖片、影片、PDF)」時,傳輸格式會變成 multipart/form-data,這時 Express 內建的 express.json() 就完全看不懂了。首先,在專案中安裝 Multer:
npm install multer
接著,在你的專案根目錄下,手動建立一個名為 uploads 的資料夾。這將是我們用來存放使用者上傳檔案的地方。
在 middlewares 資料夾下,新增一個 upload.js:
import multer from 'multer';
import path from 'path';
// 1. 設定儲存引擎 (Storage Engine)
const storage = multer.diskStorage({
// 設定檔案儲存的目的地
destination: (req, file, cb) => {
cb(null, 'uploads/'); // 存入我們剛剛建立的 uploads 資料夾
},
// 設定檔案名稱 (避免檔名重複導致覆蓋)
filename: (req, file, cb) => {
// 取得原始副檔名 (例如 .jpg, .png)
const ext = path.extname(file.originalname);
// 組合新檔名:欄位名稱 + 加上目前時間戳記 + 副檔名
const uniqueName = `${file.fieldname}-${Date.now()}${ext}`;
cb(null, uniqueName);
}
});
// 2. 設定檔案過濾器 (安全防禦:只允許圖片)
const fileFilter = (req, file, cb) => {
// 檢查 mimetype 是否為圖片
if (file.mimetype.startsWith('image/')) {
cb(null, true); // 接受檔案
} else {
cb(new Error('檔案格式錯誤,只能上傳圖片檔案!'), false); // 拒絕檔案
}
};
// 3. 匯出設定好的 multer 實例
export const upload = multer({
storage: storage,
fileFilter: fileFilter,
limits: {
fileSize: 2 * 1024 * 1024 // 限制檔案大小為 2MB
}
});
現在我們要把寫好的上傳守衛,套用到具體的 API 路由上。打開你的 routes/users.js (或是新開一個測試路由檔案):
import express from 'express';
import { upload } from '../middlewares/upload.js'; // 引入剛剛寫好的 Multer 中介軟體
const router = express.Router();
// 使用 upload.single('avatar') 攔截單一檔案
// 'avatar' 必須和前端表單 (<input type="file" name="avatar">) 的 name 屬性完全一致!
router.post('/upload-avatar', upload.single('avatar'), (req, res) => {
try {
// 如果沒有上傳檔案,req.file 會是 undefined
if (!req.file) {
return res.status(400).json({ message: '請選擇要上傳的圖片' });
}
// req.file 包含了檔案的詳細資訊
console.log("上傳成功!檔案資訊:", req.file);
res.status(200).json({
message: '大頭貼上傳成功!',
// 回傳檔案的路徑給前端,讓前端可以顯示圖片
imageUrl: `/${req.file.path}`
});
} catch (error) {
res.status(500).json({ message: '上傳失敗', error: error.message });
}
});
export default router;
你可能會問:「檔案存進 uploads 資料夾了,那前端要怎麼透過網址看到這張圖片?」
Express 預設是會阻擋任何人存取伺服器上的實體檔案的。為了讓 uploads 資料夾公開,你需要回到 app.js,加入這一行「靜態檔案託管」的設定:
// 告訴 Express:把 'uploads' 資料夾變成公開的靜態資源目錄
app.use('/uploads', express.static('uploads'));
現在,如果你的 API 回傳圖片路徑是 /uploads/avatar-1700000.jpg,前端只要訪問 http://localhost:3000/uploads/avatar-1700000.jpg,就能順利看到剛剛上傳的圖片了!