본문 바로가기
학원에서 배운 것/node.js

KDT 5th 웹개발자 입문 수업 34일차 - 2

by 쿠리의일상 2023. 3. 23.

Multer

파일을 간단하게 업로드하게 해주는 모듈

npm i -S multer 로 설치

 

파일을 업로드할 때 form 데이터가 단순 텍스트가 아니므로 인코딩 타입 속성을 추가해줘야 한다.

<form action="/dbBoard/write" method="POST" class="board_form" enctype="multipart/form-data">

enctype="multipart/form-data" 를 추가

 

<div class="form_img">
  <h3>이미지 업로드</h3>
  <input type="file" name="img" />
</div>

input 태그의 type 을 file 로 설정

 

multer 와 fs 모듈 불러오기

const multer = require('multer');
const fs = require('fs');

 

 

저장 설정

- destination : 업로드를 할 폴더 설정

- filename : 파일 이름 설정

한계 설정

- 파일 크기, 이름 같은 제한을 설정 가능

 

// 파일 업로드 설정
const dir = './uploads'; // 폴더 위치 지정은 상대 경로를 사용해야 함
// 저장 설정
const storage = multer.diskStorage({
	// null 은 모듈을 정상적으로 불러왔는지 테스트하는 인자
  destination: (req, file, cb) => { // 저장 위치 지정
    cb(null, dir);
  },
  filename: (req, file, cb) => { // 파일 이름 설정
    cb(null, file.fieldname + '_' + Date.now());
  },
});
// 한계 설정
const limits = {
  fileSize: 1024 * 1024 * 2,
};

const upload = multer({ storage, limits }); // 파일 업로드를 위한 multer 모듈을 upload 라는 변수에 담아준다

if (!fs.existsSync(dir)) fs.mkdirSync(dir); // 폴더가 존재하는지 확인하고 없다면 만들어주기

existsSync, mkdirSync 는 exists 와 mkdir 함수를 동기적으로 처리할 수 있는 함수들임

 

upload에 담아준 multer 모듈은 미들웨어처럼 넣어주면 된다.

upload.single(타입)

router.post('/write', isLogin, upload.single('img'), writeArticle);

 

업로드한 파일 정보는 결국 writeArticle 으로 이동한다.

즉 프론트에서 백으로 요청이 들어간 것이므로 req.file 에 담긴다.

const writeArticle = async (req, res) => {
  try {
    const client = await mongoClient.connect();
    const board = await client.db('kdt5').collection('board');

    console.log(req.file);

    await board.insertOne({
      USERID: req.session.userId,
      TITLE: req.body.title,
      CONTENT: req.body.content,
      IMAGE: req.file ? req.file.filename : null,
    });
    res.status(200).redirect('/dbBoard');
  } catch (err) {
    console.error(err);
    res.status(500).send(err.message + UNEXPECTED_MSG);
  }
};

<div class="content">
  <% if (ARTICLE[i].IMAGE !== null && ARTICLE[i].IMAGE !== undefined) { %>
  <img src="/uploads/<%= ARTICLE[i].IMAGE %>" width="500">
  <% } %>
</div>

 

해줘도 기본적으로 프론트에선 upload 폴더가 스태틱 폴더가 아니므로

app.js에 app.use('/uploads', express.static('uploads')); 를 해줘서 /uploads 주소에서 요청을 받았을 때 uploads 폴더를 스태틱으로 허용해줘야한다.

 

 

const modifyArticle = async (req, res) => {
  try {
    const client = await mongoClient.connect();
    const board = await client.db('kdt5').collection('board');

    const modiryArti = {
      TITLE: req.body.title,
      CONTENT: req.body.content,
    };
    if (req.file) modiryArti.IMAGE = req.file.filename;

    await board.updateOne(
      {
        _id: ObjectId(req.params.id),
      },
      {
        $set: modiryArti,
      }
    );
    res.status(200).redirect('/dbBoard');
  } catch (err) {
    console.error(err);
    res.status(500).send(err.message + UNEXPECTED_MSG);
  }
};