Express - Multer 라이브러리


multer는 Node Express 서버에서 파일 업로드를 위한 미들웨어이다. HTML에서 Form데이터를 처리하거나 Ajax를 통해 클라이언트에서 서버로 파일을 업로드할 수 있다. 

1. multer 설치


> npm i multer

2. multer(opts)


const multer = require("multer");

 

속성 설명
dest or storage 파일이 저장될 위치
fileFilter 어떤 파일을 허용할지 제어하는 함수
limits 업로드 된 데이터의 한도
preservePath 파일의 base name 대신 보존할 파일의 전체 경로

3. 업로드 규칙


1) strage / dest

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, 'uploads/data'); //파일 저장 경로
    },
    filename: (req, file, cb) => {
        cb(null, `${Date.now()}-${file.originalname}`); //파일 이름
    }
})
// 파일 저장 경로는 /uploads/data 저장
// 파일 이름은 현재시간-기존파일이름.기존확장자

 

스토리지는 업로드 파일을 디스크에 저장하기 위해 모든 제어 기능을 제공.

 

destination, filename의 두 가지 옵션이 있다. destination 옵션은 어디 폴더에 저장할지를 정한다. (사용 방법은 위 코드 참고) filename은 말 그대로 어떤 이름으로 저장할지를 설정. 아무런 설정이 없다면 랜덤 한 값으로 설정되며, 확장자까지 사라지므로 주의해야 함. file에는 아래의 정보를 포함하고 있어 참고하여 사용

 

속성 설명 기본값
fieldname 폼에 정의된 필드 명  
originalname 사용자가 업로드한 파일 명  
encoding 파일의 엔코딩 타입  
mimetype 파일의 Mime 타입  
size 파일의 바이트(byte) 사이즈  
destination 파일이 저장된 폴더 DiskStorage
filename destination 에 저장된 파일 명 DiskStorage
path 업로드된 파일의 전체 경로 DiskStorage
buffer 전체 파일의 Buffer MemoryStorage

 

규칙 없이 단순 경로만 사용 할 경우 dest 옵션에 경로만 지정하여 사용

const upload = multer({ dest: 'uploads/' })

2) Limits

Limits는 파일의 크기 제한을 지정하는 객체로 아래의 속성들을 알맞게 사용하여 업로드 파일의 용량을 제한하면 된다. 기본적으로 DoS 공격을 보호하기 위해 설정해주는 편이 좋다.

속성 설명 기본값
fieldNameSize 필드명 사이즈 최대값 100 bytes
fieldSize 필드값 사이즈 최대값 1MB
fields 파일형식이 아닌 필드의 최대 개수 무제한
fileSize multipart 형식 폼에서 최대 파일 사이즈(bytes) 무제한
files multipart 형식 폼에서 파일 필드의 최대 개수 무제한
parts For multipart forms, the max number of parts (fields + files) 무제한
headerPairs multipart 형식 폼에서 파싱할 헤더의 key=>value 쌍의 최대 개수 2000

4. upload 선언


const upload = multer({ storage : storage, limits: { fileSize: 10 * 1024 * 1024 } }); //크기 제한 : 10MB

 

지금까지 만든 storage와 limits 규칙들을 가지고 upload를 선언

5. 업로드 받기


//Front
<input type="file" name="profile" id="upload-input"/>
// Back
app.post('/upload/profile', upload.single('profile'), (req, res)=> {
    console.log(req.file);
    res.status(200).send("ok!");
});

 

.single(filedname) : filedname에 명시된 하나의 파일을 업로드받는다. input 태그에 name 속성을 지정해주면 된다. 업로드 후 req.file 에 저장

 

 

.array(filedName, [, maxCount]) : 복수의 파일을 업로드받을 경우 사용 하며, filename에 명시된 파일 전체를 배열 형태로 전달받고 maxCount로 개수의 제한을 설정한다. single과 같이 req.file 에 저장

 

 

.feilds(fields) : 인자에 명시된 여러 파일을 전달 받음. 

 

[
  { name: 'avatar', maxCount: 1 },
  { name: 'gallery', maxCount: 8 }
]

.any() : 모두 허용

6.  fileFilter 적용하기


const fileFilter = (req, file, cb) => {
  // 이 함수는 boolean 값과 함께 `cb`를 호출함으로써 해당 파일을 업로드 할지 여부를 나타낼 수 있습니다.
  // 이 파일을 거부하려면 다음과 같이 `false` 를 전달합니다:
  cb(null, false)

  // 이 파일을 허용하려면 다음과 같이 `true` 를 전달합니다:
  cb(null, true)

  // 무언가 문제가 생겼다면 언제나 에러를 전달할 수 있습니다:
  cb(new Error('I don\'t have a clue!'))
}

 

fileFilter는 업로드된 파일의 유효성 검사를 도와준다. 아래 코드는 이미지 파일만 업로드 가능하도록 유효성 작성된 코드이다.

 

const fileFilter = (req, file, cb) => {
    const typeArray = file.mimetype.split('/');
    const fileType = typeArray[1];

    if (fileType == 'jpg' || fileType == 'png' || fileType == 'jpeg' || fileType == 'gif' || fileType == 'webp') {
        req.fileValidationError = null;
        cb(null, true);
    } else {
        req.fileValidationError = "jpg,jpeg,png,gif,webp 파일만 업로드 가능합니다.";
        cb(null, false)
    }
}

 

필터의 적용은 아래와 같이 upload를 선언할 때 필터를 지정해서 적용

 

const upload = multer({
    storage : storage,
    fileFilter : fileFilter,
    limits: { 
        fileSize: 10 * 1024 * 1024 //크기 제한 : 10MB
    }
});

7. 테스트


 

전혀다른 확장자인 pptx 파일을 업로드했을 경우 위와 같은 에러가 출력된다. 물론 프론트 단에서 <input> 태그에서 허용 가능한 확장자를 지정해 줄 수 있지만 백엔드 단에서도 유효성 체크를 해주는 것이 바람직하다.

 

<input type="file" name="profile" accept="image/gif, image/jpeg, image/png, image/webp" />

 

 

GitHub - junheeleeme/node-multer-ex

Contribute to junheeleeme/node-multer-ex development by creating an account on GitHub.

github.com


8. 공식문서


 

GitHub - expressjs/multer: Node.js middleware for handling `multipart/form-data`.

Node.js middleware for handling `multipart/form-data`. - GitHub - expressjs/multer: Node.js middleware for handling `multipart/form-data`.

github.com