Node.js multer 이미지 업로드 - node.js multer imiji eoblodeu

Multer란?

Multer는 파일 업로드를 위해 사용되는 Node.js의 미들웨어입니다.

multipart/form-data 형식으로 단일 및 다중 파일 업로드를 지원하기 때문에 가장 많이 사용됩니다.

npm을 통한 multer 설치

npm install --save multer
  • https://www.npmjs.com/package/multer
  • https://github.com/expressjs/multer/blob/master/doc/README-ko.md (한국어)

multer 쉽게 설치할 수 있습니다. 위 사이트는 공식문서로 활용됩니다. (Local 환경에서 사용할 때는 많은 도움이 됐지만, S3 연결할 때는 별도의 노력이 필요했습니다.)

Multer 실제 예시

const express = require("express");
const app = express();
const multer = require("multer");
const fs = require("fs");

app.listen(3000, () => {
	const dir = "./uploads";
    if(!fs.existsSync(dir)) {
    	fs.mkdirSync(dir);
    }
    console.log("서버 실행");
});

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now())
  }
});

const upload = multer({ storage: storage })

(https://github.com/expressjs/multer/blob/master/doc/README-ko.md) 참고함
디렉토리가 존재하지 않는 경우 디렉토리를 생성하고 진행됩니다.

파일 저장 경로는 uploads 정의합니다.

이후에는 S3로 경로를 변경합니다.

filename의 경우 중복 저장 방지를 위해 뒷쪽에 Date.now()를 통해 원본 + 시간을 합쳐 저장합니다.

단일 파일 업로드 / 다중 파일 업로드 차이

POST 요청을 통해 파일을 업로드 할 수 있습니다.

중요한 부분은 upload.single('img')에서 img 입니다. 현재 Key값이 img입니다. 따라서 Client에서 Key 값 사용을 img로 해서 전달해야 합니다. 요청이 정상적으로 수행된다면 파일이 uploads 폴더에 저장됩니다.

// 단일 파일 업로드
app.post('/', upload.single('img'), (req, res, next) => {
    res.status(200).send({
        message: "Ok",
        fileInfo: req.file
    })
});

// 다중 파일 업로드
app.post('/multipart', upload.array('img'), (req, res, next) => {

    // console check
    req.files.map((data) => {
        console.log(data);
    });
    
    res.status(200).send({
        message: "Ok",
        fileInfo: req.files
    })
});

Node.js multer 이미지 업로드 - node.js multer imiji eoblodeu

🧑🏻‍💻 node.js 이미지 업로드

✔️ middleware 환경구성

node.js 에서 이미지 업로드를 위해선 form-data 형태의 데이터를 받아 처리해야 한다.
form-data 형태는 기본적으로 request에 존재한다. req의 body에 담겨있는 form-data 형태의 데이터를 처리하기위해 'multer' 라는 미들웨어를 사용한다.

npm install multer --save

💽 우선 multer를 설치한다.

✔️ multer.js 구성

나는 프로젝트 폴더 내 util이라는 폴더에 multer.js를 구성하여 이하 사항을 진행했다.

const multer = require("multer");
const path = require("path");

const fileFilter = (req, file, cb) => {
  // 확장자 필터링
  if (
    file.mimetype === "image/png" ||
    file.mimetype === "image/jpg" ||
    file.mimetype === "image/jpeg"
  ) {
    cb(null, true); // 해당 mimetype만 받겠다는 의미
  } else {
    // 다른 mimetype은 저장되지 않음
    req.fileValidationError = "jpg,jpeg,png,gif,webp 파일만 업로드 가능합니다.";
    cb(null, false);
  }
};

const upload = multer({
  storage: multer.diskStorage({
    //폴더위치 지정
    destination: (req, file, done) => {
      done(null, "/uploads");
    },
    filename: (req, file, done) => {
      const ext = path.extname(file.originalname);
      // aaa.txt => aaa+&&+129371271654.txt
      const fileName = path.basename(file.originalname, ext) + Date.now() + ext;
      done(null, fileName);
    },
  }),
  fileFilter : fileFilter,
  limits: { fileSize: 30 * 1024 * 1024 },
});

module.exports = { upload };

저장위치를 프로젝트 내 uploads 폴더로 지정해 놓고 multer의 params 부분인
storage: multer.diskStorage 안에 폴더위치와 filename을 지정해주었다.
fileFilter 함수를 만들어 jpg, jpeg, png 타입이 아닌 파일은 저장되지 않게 만들었다.
limits 를 이용해 최대 30MB 크기의 이미지 까지만 업로드 할수 있게 지정 하였다.

✔️ router.js 이미지 업로드

const { upload } = require("../utils/multer");

var app = express.Router();

// 이미지 업로드
app.post("/upload", upload.single("img"), async (req, res) => {

  const imgfile = req.file;
  console.log(imgfile);
  //
  ...
  //
  
}); //이미지 업로드 end

module.exports = app;

이미지 업로드는 middleware 자리에 들어가게 된다.
기본적으로 한개의 파일만 업로드 하는 경우는 middlewareName.single("form-data-name") 의 형태이다.
두개 이상의 파일을 업로드 하는경우는 upload.fields([{ name: 'img' }, { name: 'photos' }]) 의 형태이거나 .array() 형태로 데이터를 받는다.

🚨 주의!! front의 formdata의 이름을 미들웨어 필드의 이름과 일치시켜줘야 한다.

✔️ router.js 이미지 삭제

삭제는 DB를 삭제하기도 하지만 파일 자체를 삭제 해야한다.
파일 자체를 삭제하기 위해 file System인 fs를 설치하여 사용한다.

💽 npm install을 통해 fs 모듈을 설치
npm install fs

var fs = require("fs");
const { upload } = require("../utils/multer");

var app = express.Router();

//이미지 삭제 add (02.06 OYT)
app.delete("/upload", async (req, res) => {

  if (fs.existsSync("/uploads" + file_name)) {
    // 파일이 존재한다면 true 그렇지 않은 경우 false 반환
    try {
      fs.unlinkSync("/uploads" + file_name);
      console.log("image delete");
    } catch (error) {
      console.log(error);
    }
  }
  //
  ...
  //
}); //이미지 삭제 end

module.exports = app;

fs.existsSync 로 이미지가 있는지 확인한다.
이미지가 있다면 fs.unlinkSync 로 이미지를 삭제 한다.
파일을 직접 지우는 코드 이기에 경로를 잘 확인하고 진행해야 한다.

🙇🏻‍♂️ 이렇게 node.js에서 이미지 업로드 및 삭제의 포스팅을 끝낸다.

🙌 END