Node.js

multer 사용해서 이미지 업로드 구현

쿠와와 2021. 1. 6. 15:07

form 태그의 enctype multipart/form-data

body-parser로는 요청 본문을 해석할 수 없음

multer 패키지 필요

이미지를 먼저 업로드하고, 이미지가 저장된 경로를 반환할 것임

게시글 formsubmit할 때는 이미지 자체 대신 경로를 전송

 

fs.readdir, fs.mkdirSyncupload 폴더가 없으면 생성

multer() 함수로 업로드 미들웨어 생성

  • storage: diskStorage는 이미지를 서버 디스크에 저장(destination은 저장 경로, filename은 저장 파일명)
  • limits는 파일 최대 용량(5MB)
  • upload.single(‘img’): 요청 본문의 img에 담긴 이미지 하나를 읽어 설정대로 저장하는 미들웨어
  • 저장된 파일에 대한 정보는 req.file 객체에 담김
const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');

const { Post, Hashtag } = require('../models');
const { isLoggedIn } = require('./middlewares');

const router = express.Router();

//upload폴더를 만들어주는 것 
try {
  fs.readdirSync('uploads');
} catch (error) {
  console.error('uploads 폴더가 없어 uploads 폴더를 생성합니다.');
  fs.mkdirSync('uploads');
}
// 따로 받는 이유 -> 이미지 용량이 천자 만별이라 큰건 압축할 때 시간이 오래걸릴 수 있음 
// 이미지를 먼저 올리고 있을때 게시물을 작성한다면 시간 효율이 더 좋을 수 있다. 
// 하지만 묶어 줘야함 그래서 믿에서 front에 보내줘서 같이 보낼 수 있게 해줌 
const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, cb) {
      cb(null, 'uploads/');
    },
    filename(req, file, cb) {
      const ext = path.extname(file.originalname);
      cb(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  }),
  limits: { fileSize: 5 * 1024 * 1024 },
});

// 키가 동일해야지 받아 올 수 있음 
router.post('/img', isLoggedIn, upload.single('img'), (req, res) => {
  console.log(req.file);
  res.json({ url: `/img/${req.file.filename}` });   // 실제 파일과 요청이 다름 
});

const upload2 = multer();
router.post('/', isLoggedIn, upload2.none(), async (req, res, next) => {
  try {
    console.log(req.user);
    const post = await Post.create({
      content: req.body.content,
      img: req.body.url,
      UserId: req.user.id,
    });
    const hashtags = req.body.content.match(/#[^\s#]*/g);
    if (hashtags) {
      const result = await Promise.all(
        hashtags.map(tag => {
          return Hashtag.findOrCreate({
            where: { title: tag.slice(1).toLowerCase() },
          })
        }),
      );
      await post.addHashtags(result.map(r => r[0]));
    }
    res.redirect('/');
  } catch (error) {
    console.error(error);
    next(error);
  }
});

module.exports = router;

 

upload2.none()multipart/formdata 타입의 요청이지만 이미지는 없을 때 사용

  • 게시글 등록 시 아까 받은 이미지 경로 저장
  • 게시글에서 해시태그를 찾아서 게시글과 연결(post.addHashtags)
  • findOrCreate는 기존에 해시태그가 존재하면 그걸 사용하고, 없다면 생성하는 시퀄라이즈 메서드

 

메인 페이지(/) 요청 시 게시글을 먼저 조회한 후 템플릿 엔진 렌더링

  • include로 관계가 있는 모델을 합쳐서 가져올 수 있음
  • PostUser는 관계가 있음 (1대다)
  • 게시글을 가져올 때 게시글 작성자까지 같이 가져오는 것)

 

nodejs의 강의는 제로초님의 강의를 제가 돈을 내고 들은 후 제가 보기 위해 정리하는 것입니다. (수입창출 하지 않습니다.)

'Node.js' 카테고리의 다른 글

Nodejs 호출 서버 만들기  (0) 2021.01.10
Node에서 API 서버 만들기  (0) 2021.01.08
카카오 로그인 작업  (0) 2021.01.06
패스포트 사용하기 (로그인 과정 helper)  (0) 2021.01.05
Nodejs 데이터 베이스 셋팅하기  (0) 2021.01.05