---
# System prepended metadata

title: "\U0001F3C5 Day 33"
tags: [Node.js 直播班 - 2022 春季班]

---

---
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) |


