티스토리 뷰

BackEnd/Node.js

node.js File upload 하기

철철22 2019. 6. 4. 23:02
반응형

안녕하십니까 node js를 이용해 계속 프로젝트를 진행하고 있는데 어김없이 File Upload 기능을 구현을 해야 했습니다.

너무 귀찮은데 말이죠 ㅠㅠ

 

그래도 구현을 해야 하니 node.js는 어떻게 파일 업로드를 하는지 찾아봤습니다.

그리고 대부분이 multer라는 모듈을 이용하는 거 같습니다. (fs를 이용한 file upload도 찾았는데 참조 링크를 참조해주세요.)

 

Multer는 파일 업로드를 위해 사용되는 multipart/form-data 를 다루기 위한 node.js 의 미들웨어입니다. 효율성을 최대화하기 위해 busboy 를 기반으로 하고 있습니다.  by npm-multer

 

일단 모듈을 설치해야 합니다. 저는 역시 typescript를 사용하니 @types까지 설치!

 

npm install --save multer

npm install --save --dev @types/multer

 

메뉴얼에서는 multer를 router.use 부분에 기재를 하는 것 같습니다. ( Handler처럼 따로 빼보려다 실패했음...)

 

일단 기본적인 사용 예제입니다.

import express from "express";
import UploadController from "./UploadController";
import multer = require("multer");

export const upload = multer();

export default express
  .Router()
  .post(
    "/upload",
    [upload.array("files", 10)],
    UploadController.upload
  );

위에서는 array라고 해서 여러 파일을 받기 위해 사용했지만 .single(), .array(), fields() 이렇게 사용할 수 있습니다.

fields()는 다른 key들을 이용해서 받을 때 사용합니다.

 

 

저는 이미지 파일과 일반 파일을 분류하기 위해서 다음과 같이 사용했습니다.

import express from "express";
import UploadController from "./UploadController";
import multer = require("multer");
import fileHandler from "../../middlewares/file.handler";
import tokenHandler from "../../middlewares/token.handler";
import moment = require("moment");

export const fileStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    let date: string = moment().format("YYMMDD");
    if (file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
      cb(null, "upload/images/" + date + "/");
    } else if (file.originalname.match(/\.(txt|csv)$/)) {
      cb(null, "upload/files/" + date + "/");
    }
  },
  filename: (req, file, cb) => {
    cb(null, file.originalname);
  }
});

export const upload = multer({
  storage: fileStorage,
  limits: {
    files: 10
  }
});

export default express
  .Router()
  .post(
    "/upload",
    [tokenHandler, fileHandler, upload.array("files", 10)],
    UploadController.upload
  );

개발을 하면서 난관에 부딪힌 부분이 있는데 위의 destination의 req입니다.

저는 req가 express.Request 속성인 줄 알고 Client에서 받은 req를 받을 수 있을 줄 알았는데,

저 속정은 Multer의 Express.Request 속성이어서 req.file과 req.files밖에 못 받더라고요...

그래서 어쩔 수 없이 확장자 명을 받아서 저장 위치를 따로 분류를 했습니다.

 

그리고 fileHandler라는 것을 만들어서 상위 폴더가 없으면 폴더를 만들어 주는 로직을 추가해줬습니다.

import { Request, Response, NextFunction } from "express";
import fs from "fs";
import moment = require("moment");

export default function fileHandler(
  req: Request,
  res: Response,
  next: NextFunction
) {
  let date: string = moment().format("YYMMDD");
  let fileDir: string = "upload/files/" + date;
  let imageDir: string = "upload/images/" + date;
  try {
    const stat = fs.lstatSync(fileDir);
  } catch (err) {
    fs.mkdirSync(fileDir, { recursive: true });
    fs.mkdirSync(imageDir, { recursive: true });
  } finally {
    next();
  }
}

 

파일 저장을 확인해보니 잘 찍히더라고요.

좀 더 나은 방법을 생각해 봤는데 아직까지는 생각이 안 나더라고요... 나중에 좋은 예제를 찾아서 활용해 볼 수 있으면 좋겠네요.

 

 

 

 

참조 

https://victorydntmd.tistory.com/39|

 

multer

https://www.npmjs.com/package/multer

 

fs를 이용한 file upload
https://infodbbase.tistory.com/59

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함