--- tags: Node.js 直播班 - 2022 春季班 --- # 🏅 Day 33 ## multer 處理上傳檔案 接下來第七週會製作上傳圖片功能,並實作 Imgur 串接 使用者上傳圖片 POST 請求,檔案會以 form data 的形式傳送到後端, 因此會使用到 multer 套件處理接收到的資料 Multer 為一個 node.js middleware,處理 multipart/form-data 資料,主要用於上傳檔案 **範例** ```javascript // app.js const uploadRouter = require('./routes/upload'); app.use('/api/v1/upload', uploadRouter); // routes/upload.js const multer = require('multer') const upload = multer().any(); app.post('/', function (req, res) { upload(req, res, () => { // 這裡先回傳以下,接下來會串接 Imgur 將以成功處理的圖片上傳至 Imgur 相簿 res.send({ status: 'success' }); }) ``` 其中 `multer()` 可以加入 options 設定,這裡主要會加入 [fileFilter](https://github.com/expressjs/multer#filefilter) 及 [limits](https://github.com/expressjs/multer#limits) 限制上傳圖片檔案類型以及最大檔案容量 **範例** ```javascript // routes/upload.js const multer = require('multer') const path = require('path'); const upload = multer({ limits: { fileSize: 2 * 1024 * 1024, }, fileFilter(req, file, cb) { const ext = path.extname(file.originalname).toLowerCase(); // path.extname() 取得副檔名(如 .jpg) if (ext !== '.jpg' && ext !== '.png' && ext !== '.jpeg') { // 拒絕上傳的檔案 cb('檔案格式錯誤,僅限上傳 jpg、jpeg 與 png 格式。'); } // 接受檔案 cb(null, true); }, }).any(); ``` ### 參考資源 [path.extname(path)](https://nodejs.org/api/path.html#pathextnamepath) [expressjs / multer ](https://github.com/expressjs/multer) ### 題目(將答案寫在 HackMD 並提交至回報區) 請參考上方範例,加入上傳圖片路由 POST `/api/v1/upload`,使用 multer 套件處理 form-data,若有上傳圖片成功則回傳成功訊息 :::spoiler POSTMAN 範例圖 ![](https://i.imgur.com/eUg6H4f.png) 選擇 `form-data` 並選擇傳送 file ::: 回報流程 --- 請同學依照下圖教學觀看解答、回報答案: ![](https://i.imgur.com/QtL8zEW.png) 回報格式:請在「回報區」貼上 CodePen 或 HackMD 連結回報答案 (為了統計人數,請同學依序加上「報數」) <!-- 解答 ```javascript // app.js const uploadRouter = require('./routes/upload'); app.use('/api/v1/upload', uploadRouter); // routes/upload.js const multer = require('multer'); const path = require('path'); const upload = multer({ limits: { fileSize: 2 * 1024 * 1024, }, fileFilter(req, file, cb) { const ext = path.extname(file.originalname).toLowerCase(); if (ext !== '.jpg' && ext !== '.png' && ext !== '.jpeg') { cb('檔案格式錯誤,僅限上傳 jpg、jpeg 與 png 格式。'); } cb(null, true); }, }).any(); app.post('/', function (req, res) { upload(req, res, () => { // 這裡先回傳以下,接下來會串接 Imgur 將以成功處理的圖片上傳至 Imgur 相簿 res.send({ status: 'success' }); }) ``` --> 回報區 --- | 報數 | 組別 / 名字 | codepen / hackMD / 其他回饋 | | ---- | ---------------- | -------------------------------------------------- | | 1 | 第 9 組 / 黃士桓 | [HackMD](https://hackmd.io/7369A7JaQ3q_8D4X9aoyXQ) | | 2 | 第 14 組|East | [HackMD](https://hackmd.io/wDrcSmJPQnGjK8LziAk3bQ) | | 3 | 第 4 組|苡安 | [HackMD](https://hackmd.io/GgDh77JrROGwZMqnMcNBPg) | | 4 | 第 4 組|小宥 | [HackMD](https://hackmd.io/HRQ97Ze3S8aVkiYNF_of3A) | | 5 | 第 9 組 / konstante |[HackMD](https://hackmd.io/Vs8_n3dxS5m4GobnWHwCmA?edit) | | 5 | 第 5 組@Hazel |[HackMD@Hazel](https://hackmd.io/@hazelwu/day33) | | 6 | 第 2 組 wendy | [HackMD](https://hackmd.io/80FIwll1QUa4u0-WoBv-hQ#20220524)| | 7 | 第 3 組|Hobby |[HackMD](https://hackmd.io/@hobbyling/day33) | | 8 | 第 12 組|Jimmy |[HackMD](https://hackmd.io/mPEzAMwZTXC0Rdzbb7piVA) | | 9 | 第 11 組|Han Lai |[HackMD](https://hackmd.io/DadlkifwRp2cYd70Enb4Fw?view) | | 10 | 第 16 組 / 皓皓 |[HackMD](https://hackmd.io/@cutecat8110/HJT2liR9q) |