본문 바로가기
TIL

TIL 240604 - multer 오류 및 어려웠던 점 해결

by lemonpie611 2024. 6. 4.

은 어제 S3 사용하다가 안됐던것 마저 적음

1. 기본 코드 

local에 저장하는것, aws s3에 저장하는것 둘다 해봤다.

//multer.js

import AWS from 'aws-sdk'
import multer from 'multer';
import multerS3 from 'multer-s3'
import path from 'path';
import dotEnv from "dotenv";

dotEnv.config();

const s3 = new AWS.S3({
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    region: 'ap-northeast-2',
});

// 확장자 검사 목록
const allowedExtensions = ['.png', '.jpg', '.jpeg', '.bmp', '.gif'];

// 로컬에 저장
const uploadLocal = multer({
  // 파일 저장 위치 (disk , memory 선택)
  storage: multer.diskStorage({
      destination: function (req, file, done) {
          done(null, 'uploads/');
      },
      filename: function (req, file, done) {
          const ext = path.extname(file.originalname);
          done(null, path.basename(file.originalname, ext) + Date.now() + ext);
      }
  }),
  // 파일 허용 사이즈 (5 MB)
  limits: { fileSize: 5 * 1024 * 1024 }
});

// s3에 저장
const upload = multer({
    storage: multerS3({
        s3         : s3,
        bucket     : process.env.AWS_BUCKET,
        contentType: multerS3.AUTO_CONTENT_TYPE,
        key        : (req, file, callback) => {
            
            // 오늘 날짜 구하기
            const today = new Date();
            const currentYear = today.getFullYear();
            const currentMonth = today.getMonth() + 1;
            const currentDate = today.getDate();
            const date = `${currentYear}-${currentMonth}-${currentDate}`;
            
            // 임의번호 생성
            let randomNumber = '';
            for (let i = 0; i < 8; i++) {
                randomNumber += String(Math.floor(Math.random() * 10));
            }
            
            // 확장자 검사
            const extension = path.extname(file.originalname).toLowerCase();
            if (!allowedExtensions.includes(extension)) {
                return callback(new Error('확장자 에러'));
            }
            
            // folder라는 파일 내부에 업로드한 사용자에 따라 임의의 파일명으로 저장
            callback(null, `folder/${date}_${randomNumber}`);
        },
        // acl 권한 설정
        acl        : 'public-read-write'
    }),
    // 이미지 용량 제한 (5MB)
    limits: {
        fileSize: 5 * 1024 * 1024
    }
});

export { upload, uploadLocal };
// router.js

import express from 'express';
import { upload, uploadLocal } from './multer.middleware.js';

const router = express.Router();

//로컬에 저장
router.post('/uploadLocal', uploadLocal.single('file'), function (req, res, next) {
  const { wow } = req.body;
  res.send({
      wow,
  });
});

//여러개
router.post('/uploads', upload.array('file', 2), function (req, res, next) {
  const wow = req.body.wow;
  const loc = req.files.map((cur) => {
    return { location: cur.location };
  })
  res.send({
      fileLocation: loc,
      wow,
  });
});

//한개
router.post('/upload', upload.single('file'), function (req, res, next) {
  const wow = req.body.wow;
  const loc = req.file.location;
  res.send({
      fileLocation: loc,
      wow,
  });
});

export default router;
// app.js

import express from 'express';
// import AWS from 'aws-sdk'
// import multer from 'multer';
// import multerS3 from 'multer-s3'
import dotEnv from "dotenv";
import multerRouter from './multer.router.js';


dotEnv.config();

const app = express();

app.use('/', multerRouter);

app.listen(3000, () => {
    console.log("서버 실행");
});

 

2. insomnia에서 실행 방법

 

Body > Multipart 선택 > Add 클릭해서 항목 추가 > 타입을 파일로 바꾼 후 파일 가져오기 > name 지정

 

3. 오류 1 -  MulterError: Unexpected field

field 값이 일치하지 않아 발생

insomnia에서 파일을 업로드할 때 name을 upload.single() 의 인자 이름과 같아야 한다. 코드에서 'file'로 지정해놨으므로  insomnia에서도 file이라고 입력한다.

 

4. 오류 2 - this.client.send is not a function

multer-s3랑 aws-sdk 버전이 맞지 않아서 발생하는 에러이다.

내 경우 multer-s3는 3.xx, aws-sdk는 2.xx 이기 때문에, multer-s3를 다운그레이드 시켜줘야 한다.

yarn upgrade (패키지명)@(버전)

yarn upgrade multer-s3@2

5. 결과