multer

multer

  • body-parser๋กœ๋Š” ์š”์ฒญ ๋ณธ๋ฌธ์„ ํ•ด์„ํ•  ์ˆ˜ ์—†์–ด์„œ multer๋ผ๋Š” ํŒจํ‚ค์ง€๊ฐ€ ํ•„์š”.

  • ์ด๋ฏธ์ง€/๋™์˜์ƒ ํŒŒ์ผ ์—…๋กœ๋“œ๋ฅผ ๋„์™€์คŒ

์‚ฌ์šฉ๋ฐฉ๋ฒ•

const multer = require('multer');
const fs = require('fs');

try {
  fs.readdirSync('uploads');
} catch (error) {
  console.error('uploads ํด๋”๊ฐ€ ์—†์–ด uploads ํด๋”๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.');
  fs.mkdirSync('uploads');
}

const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, done) {
      done(null, 'uploads/'); // uploads/ ํด๋”์— ์ €์žฅํ•˜๊ฒ ๋‹ค
    },
    filename(req, file, done) {
      const ext = path.extname(file.originalname);
      done(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  }),
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
});

app.get('/upload', (req, res) => {
  res.sendFile(path.join(__dirname, 'multipart.html'));
});

app.post('/upload', upload.single('image'), (req, res) => {
  console.log(req.file);
  res.send('ok');
});

single image

์ „์ฒด์ฝ”๋“œ

client

multer.html

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>multer</title>
  </head>
  <body>
    multer
    <form id="form" action="/upload" method="post" enctype="multipart/form-data">
      <input type="file" name="image" />
      <input type="file" name="image2" />
      <input type="text" name="title" />
      <button type="submit">์—…๋กœ๋“œ</button>
    </form>
  </body>
  <script>
    document.getElementById('form').addEventListener('submit', (e) => {
      e.preventDefault();

      const formData = new FormData();
      formData.append('image', e.target.image.files[0]);
      formData.append('title', e.target.title.value);
      axios.post('/upload', formData);
    });
  </script>
  <script
    src="<https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.4/axios.min.js>"
    integrity="sha512-LUKzDoJKOLqnxGWWIBM4lzRBlxcva2ZTztO8bTcWPmDSpkErWx0bSP4pdsjNH8kiHAUPaT06UXcb+vOEZH+HpQ=="
    crossorigin="anonymous"
    referrerpolicy="no-referrer"
  ></script>
</html>

backend

app.js

const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const dotenv = require('dotenv');
const path = require('path');
const multer = require('multer');
const fs = require('fs');

dotenv.config();
const app = express();
app.set('port', process.env.PORT || 3000);

app.use(morgan('dev'));
app.use('/', express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
  session({
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
      httpOnly: true,
      secure: false,
    },
    name: 'session-cookie',
  })
);

// ์„œ๋ฒ„ ์‹œ์ž‘์ „์— uploads ํด๋”๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ๊ณ , ์—†์œผ๋ฉด ๋งŒ๋“ ๋‹ค
try {
  fs.readdirSync('uploads');
} catch (error) {
  console.error('uploads ํด๋”๊ฐ€ ์—†์–ด uploads ํด๋”๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.');
  fs.mkdirSync('uploads');
}

const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, done) {
      // done(์—๋Ÿฌ ์ฒ˜๋ฆฌ, ์ €์žฅํ•  ๊ณณ)
      done(null, 'uploads/'); // uploads/ ํด๋”์— ์ €์žฅํ•˜๊ฒ ๋‹ค
    },
    filename(req, file, done) {
      const ext = path.extname(file.originalname); // ํ™•์žฅ์ž ์ถ”์ถœ
      done(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  }),
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
});

app.get('/upload', (req, res) => {
  res.sendFile(path.join(__dirname, 'multer.html'));
});

// upload.single() ํŒŒ์ผ ํ•˜๋‚˜๋งŒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜
// <input type="file" name="image" /> name="image"
app.post('/upload', upload.single('image'), (req, res) => {
  console.log('req.file>>', req.file);
  res.send('ok');
});

app.get(
  '/',
  (req, res, next) => {
    console.log('GET / ์š”์ฒญ์—์„œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.');
    next();
  },
  (req, res) => {
    throw new Error('์—๋Ÿฌ๋Š” ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด๋กœ ๊ฐ‘๋‹ˆ๋‹ค.');
  }
);

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '๋ฒˆ ํฌํŠธ์—์„œ ๋Œ€๊ธฐ ์ค‘');
});

// req.file>> {
//   fieldname: 'image',
//   originalname: '1123.png',
//   encoding: '7bit',
//   mimetype: 'image/png',
//   destination: 'uploads/',
//   filename: '11231680412337468.png',
//   path: 'uploads/11231680412337468.png',
//   size: 102443
// }

multiple images

multer.html

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>multer</title>
  </head>
  <body>
    multer
    <form id="form" action="/upload" method="post" enctype="multipart/form-data">
      <input type="file" name="image" multiple />
      <input type="text" name="title" />
      <button type="submit">์—…๋กœ๋“œ</button>
    </form>
  </body>
  <script>
    document.getElementById('form').addEventListener('submit', (e) => {
      e.preventDefault();

      const formData = new FormData();
      const imageFiles = e.target.images.files;
      for (let i = 0; i < imageFiles.length; i++) {
        formData.append('image', imageFiles[i]);
      }
      console.log('formData', formData);
      formData.append('title', e.target.title.value);

      axios.post('/upload', formData);
    });
  </script>
  <script
    src="<https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.4/axios.min.js>"
    integrity="sha512-LUKzDoJKOLqnxGWWIBM4lzRBlxcva2ZTztO8bTcWPmDSpkErWx0bSP4pdsjNH8kiHAUPaT06UXcb+vOEZH+HpQ=="
    crossorigin="anonymous"
    referrerpolicy="no-referrer"
  ></script>
</html

app.js

  • ์ฃผ์š” ๋ณ€๊ฒฝ์ 

    • upload.sinlge โ†’ **upload.array**

    • req.file โ†’ **req.files**

const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const dotenv = require('dotenv');
const path = require('path');
const multer = require('multer');
const fs = require('fs');

dotenv.config();
const app = express();
app.set('port', process.env.PORT || 3000);

app.use(morgan('dev'));
app.use('/', express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
  session({
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
      httpOnly: true,
      secure: false,
    },
    name: 'session-cookie',
  })
);

// ์„œ๋ฒ„ ์‹œ์ž‘์ „์— uploads ํด๋”๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ๊ณ , ์—†์œผ๋ฉด ๋งŒ๋“ ๋‹ค
try {
  fs.readdirSync('uploads');
} catch (error) {
  console.error('uploads ํด๋”๊ฐ€ ์—†์–ด uploads ํด๋”๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.');
  fs.mkdirSync('uploads');
}

const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, done) {
      // done(์—๋Ÿฌ ์ฒ˜๋ฆฌ, ์ €์žฅํ•  ๊ณณ)
      done(null, 'uploads/'); // uploads/ ํด๋”์— ์ €์žฅํ•˜๊ฒ ๋‹ค
    },
    filename(req, file, done) {
      const ext = path.extname(file.originalname); // ํ™•์žฅ์ž ์ถ”์ถœ
      done(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  }),
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
});

app.get('/upload', (req, res) => {
  res.sendFile(path.join(__dirname, 'multer.html'));
});

// upload.single() ํŒŒ์ผ ํ•˜๋‚˜๋งŒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜
// <input type="file" name="image" /> name="image"
app.post('/upload', upload.array('image'), (req, res) => {
  console.log('req.file>>', req.files);
  res.send('ok');
});

app.get(
  '/',
  (req, res, next) => {
    console.log('GET / ์š”์ฒญ์—์„œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.');
    next();
  },
  (req, res) => {
    throw new Error('์—๋Ÿฌ๋Š” ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด๋กœ ๊ฐ‘๋‹ˆ๋‹ค.');
  }
);

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '๋ฒˆ ํฌํŠธ์—์„œ ๋Œ€๊ธฐ ์ค‘');
});

// req.file>> {
//   fieldname: 'image',
//   originalname: '1123.png',
//   encoding: '7bit',
//   mimetype: 'image/png',
//   destination: 'uploads/',
//   filename: '11231680412337468.png',
//   path: 'uploads/11231680412337468.png',
//   size: 102443
// }

multiple images 2

multer.html

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>multer</title>
  </head>
  <body>
    multer
    <form id="form" action="/upload" method="post" enctype="multipart/form-data">
      <input type="file" name="image1" />
      <input type="file" name="image2" />
      <input type="file" name="image3" />
      <input type="text" name="title" />
      <button type="submit">์—…๋กœ๋“œ</button>
    </form>
  </body>
  <script>
    document.getElementById('form').addEventListener('submit', (e) => {
      e.preventDefault();
      const formData = new FormData();
      formData.append('image1', e.target.image1.files[0]);
      formData.append('image2', e.target.image2.files[0]);
      formData.append('image3', e.target.image3.files[0]);
      formData.append('title', e.target.title.value);

      axios.post('/upload', formData);
    });
  </script>
  <script
    src="<https://cdnjs.cloudflare.com/ajax/libs/axios/1.3.4/axios.min.js>"
    integrity="sha512-LUKzDoJKOLqnxGWWIBM4lzRBlxcva2ZTztO8bTcWPmDSpkErWx0bSP4pdsjNH8kiHAUPaT06UXcb+vOEZH+HpQ=="
    crossorigin="anonymous"
    referrerpolicy="no-referrer"
  ></script>
</html>

app.js

const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const dotenv = require('dotenv');
const path = require('path');
const multer = require('multer');
const fs = require('fs');

dotenv.config();
const app = express();
app.set('port', process.env.PORT || 3000);

app.use(morgan('dev'));
app.use('/', express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
  session({
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
    cookie: {
      httpOnly: true,
      secure: false,
    },
    name: 'session-cookie',
  })
);

// ์„œ๋ฒ„ ์‹œ์ž‘์ „์— uploads ํด๋”๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ๊ณ , ์—†์œผ๋ฉด ๋งŒ๋“ ๋‹ค
try {
  fs.readdirSync('uploads');
} catch (error) {
  console.error('uploads ํด๋”๊ฐ€ ์—†์–ด uploads ํด๋”๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.');
  fs.mkdirSync('uploads');
}

const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, done) {
      // done(์—๋Ÿฌ ์ฒ˜๋ฆฌ, ์ €์žฅํ•  ๊ณณ)
      done(null, 'uploads/'); // uploads/ ํด๋”์— ์ €์žฅํ•˜๊ฒ ๋‹ค
    },
    filename(req, file, done) {
      const ext = path.extname(file.originalname); // ํ™•์žฅ์ž ์ถ”์ถœ
      done(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  }),
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB
});

app.get('/upload', (req, res) => {
  res.sendFile(path.join(__dirname, 'multer.html'));
});

// upload.single() ํŒŒ์ผ ํ•˜๋‚˜๋งŒ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด ํ•จ์ˆ˜
// <input type="file" name="image" /> name="image"
app.post(
  '/upload',
  upload.fields(
    [{ name: 'image1', limits: 5 }, { name: 'image2' }, { name: 'image3' }],
    (req, res) => {
      // console.log('req.file>>', req.files.image1);
      // console.log('req.file>>', req.files.image2);
      // console.log('req.file>>', req.files.image3);
      res.send('ok');
    }
  )
);

app.get(
  '/',
  (req, res, next) => {
    console.log('GET / ์š”์ฒญ์—์„œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.');
    next();
  },
  (req, res) => {
    throw new Error('์—๋Ÿฌ๋Š” ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฏธ๋“ค์›จ์–ด๋กœ ๊ฐ‘๋‹ˆ๋‹ค.');
  }
);

app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).send(err.message);
});

app.listen(app.get('port'), () => {
  console.log(app.get('port'), '๋ฒˆ ํฌํŠธ์—์„œ ๋Œ€๊ธฐ ์ค‘');
});

Last updated