λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
[개발] Practice/Node.js MongoDB

[Node.js / MongoDB] 이미지 μ—…λ‘œλ“œ & 이미지 μ„œλ²„ λ§Œλ“€κΈ°

by Connecting-the-dots 2022. 3. 16.
728x90
λ°˜μ‘ν˜•

πŸ’‘ μ‹€μŠ΅ 포인트!

  • μ—…λ‘œλ“œ νŽ˜μ΄μ§€λ₯Ό λ§Œλ“€μ–΄μ„œ ν•΄λ‹Ή νŽ˜μ΄μ§€μ—μ„œ νŒŒμΌμ„ μ—…λ‘œλ“œν•  경우 이미지인 κ²½μš°μ—λ§Œ μ •μƒμ μœΌλ‘œ μ—…λ‘œλ“œκ°€ λ˜λ„λ‘ ν•œλ‹€.
  • μ—…λ‘œλ“œν•œ μ΄λ―Έμ§€λŠ” μž‘μ—…ν•˜λŠ” ν•˜λ“œ 내에 μ €μž₯되고, μ €μž₯된 이미지λ₯Ό νŠΉμ • νŽ˜μ΄μ§€λ‘œ 뢈러올 수 μžˆλ„λ‘ ν•œλ‹€.

πŸ’œ μ—…λ‘œλ“œν•œ 이미지λ₯Ό μ €μž₯ν•˜λŠ” 방법 μ•Œμ•„λ³΄κΈ°

  • μ–΄λ–€ μ‚¬μ΄νŠΈλ₯Ό μš΄μ˜ν•˜λ“  이미지λ₯Ό μ—…λ‘œλ“œν•˜κ³  λ³΄μ—¬μ€˜μ•Ό ν•˜λŠ” 일이 많이 λ°œμƒν•˜λ―€λ‘œ, 이미지λ₯Ό μ–΄λ–»κ²Œ 어디에 μ €μž₯할지에 λŒ€ν•œ 고민은 ν•„μš”ν•˜λ‹€.

     1. JavaScript 파일 κ·Όμ²˜μ— 폴더λ₯Ό ν•˜λ‚˜ λ§Œλ“€μ–΄μ„œ μ €μž₯ν•˜λŠ” 방법 : μ˜€λŠ˜ μ‹€μŠ΅ λ•Œ μ‚¬μš©

     2. μ•„λ§ˆμ‘΄ λ“± ν•˜λ“œλ₯Ό κ΅¬λ§€ν•˜μ—¬ μ €μž₯ν•˜λŠ” 방법 (Amazon S3) : μ €μž₯ν•  이미지가 λ§Žμ€ 경우 μ‚¬μš©

     3. DB 에 직접 μ €μž₯ν•˜λŠ” 방법

  • 이 방법듀 쀑 3번째 방법은 속도, λΉ„μš©, μš©λŸ‰ λ“± λ‹€μ–‘ν•œ μΈ‘λ©΄μ—μ„œ 쒋은 λ°©λ²•μ΄λΌν•˜κΈ°μ—” μ–΄λ €μš°λ―€λ‘œ 주둜 1λ²ˆμ§Έλ‚˜ 2번째 방법을 μ‚¬μš©ν•œλ‹€.
  • ν•˜μ§€λ§Œ 이미지λ₯Ό λˆ„κ°€, 어디에, μ–΄λ–€ μ΄λ¦„μœΌλ‘œ μ—…λ‘œλ“œν–ˆλŠ”μ§€μ™€ 같은 메타 μ •λ³΄λŠ” DB 에 μ €μž₯ν•˜λŠ” 것이 μ›Ήκ°œλ°œ κ΄€μŠ΅μ΄λ‹ˆ κΈ°μ–΅ν•΄λ‘μž.

πŸ’œ 이미지λ₯Ό μ—…λ‘œλ“œν•  νŽ˜μ΄μ§€ λ§Œλ“€κΈ°

  • μ—…λ‘œλ“œ νŽ˜μ΄μ§€μ—λŠ” μ—…λ‘œλ“œ λ²„νŠΌκ³Ό 전솑 λ²„νŠΌλ§Œ 있으면 μΆ©λΆ„ν•˜λ‹€.

🀍 μ—…λ‘œλ“œ EJS 파일 λ§Œλ“€κΈ°

  <h4 class="container mt-5"><strong>μ—…λ‘œλ“œ νŽ˜μ΄μ§€</strong></h4>
  <div class="container mt-4">
      <form action="/upload" method="POST" enctype="multipart/form-data">
          <input type="file" name="image">
          <button type="submit" class="btn btn-primary">μ—…λ‘œλ“œ</button>
      </form>
  </div>
  • form νƒœκ·Έμ— action μ†μ„±μ—λŠ” /upload 경둜λ₯Ό, enctype μ—λŠ” multipart/form-data λ₯Ό μž‘μ„±ν•΄μ£Όμ—ˆλ‹€.
    (참고둜 enctype 은 λ³΄λ‚΄λŠ” 파일의 인코딩 ν˜•μ‹μœΌλ‘œ, νŒŒμΌμ΄λ‚˜ 이미지 μ—…λ‘œλ“œμ˜ 경우 multipart/form-data λ₯Ό μ‚¬μš©ν•˜λŠ” 게 μ’‹λ‹€κ³  ν•œλ‹€.)
  • input νƒœκ·Έμ—λŠ” type 을 file 둜 μž‘μ„±ν•΄μ£Όμ—ˆλ‹€. μ΄λ ‡κ²Œ μž‘μ„±ν•˜λ©΄ 파일 선택 λ²„νŠΌ 및 μ„ νƒλœ 파일λͺ…이 ν‘œμ‹œν•˜λŠ” 뢀뢄이 생긴 κ±Έ 확인할 수 μžˆλ‹€.
  • input νƒœκ·Έμ— name 속성을 μΆ”κ°€ν•˜μ—¬ image λΌλŠ” 값을 λ„£μ–΄μ£Όμ—ˆλ‹€. (이 뢀뢄은 μΆ”ν›„ μ‚¬μš© μ˜ˆμ •)
  • button νƒœκ·Έμ˜ type 도 λ‹€λ₯Έ 폼 μ–‘μ‹μ—μ„œμ™€ λ™μΌν•˜κ²Œ form λ‚΄μš©μ„ 전솑할 수 μžˆλ„λ‘ submit 으둜 μž‘μ„±ν•΄μ£Όμ—ˆλ‹€.

🀍 JavaScript νŒŒμΌμ—μ„œ λΌμš°νŒ… μ„€μ •ν•˜κΈ°

app.get('/upload', function(req, res){
    res.render('upload.ejs')
})
  • λˆ„κ΅°κ°€κ°€ /upload 경둜둜 GET μš”μ²­μ„ ν•˜λŠ” 경우, μ—…λ‘œλ“œ νŽ˜μ΄μ§€κ°€ λ‚˜μ˜¬ 수 있게 μ„€μ •ν•΄μ£Όμ—ˆλ‹€.

πŸ’œ μ—…λ‘œλ“œν•œ 이미지 ν•˜λ“œμ— μ €μž₯ν•  수 있게 μ…‹νŒ…ν•˜κΈ°

  • μ‚¬μš©μžκ°€ μ—…λ‘œλ“œν•œ 이미지λ₯Ό μ„œλ²„λ₯Ό 돌리고 μžˆλŠ” 컴퓨터에 κ·ΈλŒ€λ‘œ μ €μž₯ν•΄λ³΄μ•˜λ‹€.
  • 참고둜 λ‚˜λŠ” μž‘μ—…ν΄λ” 내에 public/images λΌλŠ” 폴더λ₯Ό μƒμ„±ν•˜μ—¬ μ—…λ‘œλ“œν•œ 이미지λ₯Ό μ €μž₯ν–ˆλ‹€.

🀍 multer 라이브러리 μ„€μΉ˜ν•˜κΈ°

  • multipart/form-data λ₯Ό 톡해 μ—…λ‘œλ“œν•œ νŒŒμΌμ„ μ‰½κ²Œ μ €μž₯ 및 처리λ₯Ό ν•˜κΈ° μœ„ν•΄μ„œλŠ” multer 라이브러리 μ„€μΉ˜κ°€ ν•„μš”ν•˜λ‹€.
  • 터미널을 μΌ  ν›„ npm install multer λ₯Ό μž…λ ₯ν•œλ‹€.
  • μ„€μΉ˜κ°€ λλ‚˜λ©΄ JavaScript νŒŒμΌμ— multer μ…‹νŒ…μ„ λ‹€μŒκ³Ό 같이 μ§„ν–‰ν•˜λ©΄ λœλ‹€.
let multer = require('multer'); // μ„€μΉ˜ν•΄λ‘” multer λ₯Ό κ°€μ Έλ‹€ μ“°κ² λ‹€λŠ” 의미

var storage = multer.diskStorage({
    destination : function(req, file, cb){
        cb(null, './public/images')
    },
    filename : function(req, file, cb){
        cb(null, file.originalname)
    }
});

var upload = multer({storage : storage});

1. .diskStorage() : μ—…λ‘œλ“œν•œ νŒŒμΌμ„ ν•˜λ“œμ— μ €μž₯ν•˜λŠ” μš©λ„μ˜ ν•¨μˆ˜μ΄λ‹€.

   (λž¨μ— μ €μž₯ν•˜κ³  μ‹Άλ‹€λ©΄ memoryStorage 라고 써도 λ˜μ§€λ§Œ, νœ˜λ°œμ„±μž„μ„ κ°μ•ˆν•΄μ•Ό ν•œλ‹€.)

2. destination : μ—…λ‘œλ“œν•œ νŒŒμΌμ„ μ €μž₯ν•  ν•˜λ“œμ˜ 경둜λ₯Ό μ„€μ •ν•˜λŠ” 뢀뢄이닀.

   (λ‚˜λŠ” μ•žμ„œ λ§ν–ˆλ“―μ΄ public/images 폴더λ₯Ό μƒμ„±ν•˜μ—¬ μ €μž₯ν•  것이라 μœ„μ™€ 같이 μ½”λ“œλ₯Ό μž‘μ„±ν–ˆλ‹€.)

3. filename : μ €μž₯ν•  λ•Œ μ–΄λ–€ μ΄λ¦„μœΌλ‘œ 파일의 이름을 μ €μž₯할지 κ²°μ •ν•˜λŠ” 뢀뢄이닀.

   (file.originalname 이라고 μž‘μ„±ν•˜λ©΄ 원본 κ·ΈλŒ€λ‘œ μ €μž₯ν•˜κ² λ‹€λŠ” μ˜λ―Έμ΄λ‹€.)

4. var upload : upload λΌλŠ” λ³€μˆ˜λ₯Ό μƒμ„±ν•˜μ—¬ multer μ…‹νŒ…μ„ μ €μž₯ν•΄μ£Όλ©΄ 끝!


πŸ’œ ν•„ν„° κΈ°λŠ₯으둜 μ›ν•˜λŠ” ν™•μž₯μžμ— ν•΄λ‹Ήν•˜λŠ” μ—…λ‘œλ“œ 파일만 κ±°λ₯΄λŠ” 방법 μ•Œμ•„λ³΄κΈ°

var path = require('path');

var upload = multer({
    storage: storage,
    fileFilter: function (req, file, cb) {
        var ext = path.extname(file.originalname);
        if(ext !== '.png' && ext !== '.jpg' && ext !== '.jpeg') {
            return cb(new Error('PNG, JPG 파일만 μ—…λ‘œλ“œ κ°€λŠ₯ν•©λ‹ˆλ‹€.'));
        }
        cb(null, true)
    },
    limits:{
        fileSize: 1024 * 1024
    }
});
  • μ…‹νŒ…ν•˜λŠ” λΆ€λΆ„ μ•ˆμ— fileFilter λΌλŠ” ν•­λͺ©μ„ μΆ”κ°€ν•˜λ©΄ λœλ‹€.
  • path λΌλŠ” λ³€μˆ˜λŠ” node.js κΈ°λ³Έ λ‚΄μž₯ 라이브러리 path λ₯Ό ν™œμš©ν•΄ 파일의 경둜, 이름, ν™•μž₯자 등을 μ•Œμ•„λ‚Ό λ•Œ μ‚¬μš©ν•œλ‹€.
  • limits λŠ” 파일 μ‚¬μ΄μ¦ˆμ˜ μ œν•œμ„ κ±Έκ³  싢을 λ•Œ μ‚¬μš©ν•œλ‹€.

πŸ’œ 이미지 전솑 싀행해보기

app.post('/upload', upload.single('image'), function(req, res){
    res.send('파일 μ—…λ‘œλ“œ μ™„λ£Œ')
});
  • λˆ„κ΅°κ°€κ°€ μ—…λ‘œλ“œ νŽ˜μ΄μ§€μ—μ„œ 전솑 λ²„νŠΌμ„ 눌러 /upload 경둜둜  POST μš”μ²­μ„ ν•˜λ©΄, 파일의 전솑과 ν•¨κ»˜ '파일 μ—…λ‘œλ“œ μ™„λ£Œ' λΌλŠ” 문ꡬλ₯Ό λ„μ›Œμ£Όλ„λ‘ ν–ˆλ‹€.
  • 즉, λˆ„κ΅°κ°€κ°€ /upload 둜 POST μš”μ²­μ„ ν•˜λ©΄ upload.single('input 의 name 속성') μ΄λΌλŠ” 미듀웨어가 싀행이 되고 multer μ…‹νŒ…λŒ€λ‘œ μ—…λ‘œλ“œν•œ 파일이 μ²˜λ¦¬λ˜λŠ” 것이닀.
    (input 의 name μ†μ„±μ—λŠ” 본인이 μ„€μ •ν•œ name 속성값, 즉 λ‚˜μ˜ κ²½μš°μ—λŠ” image λ₯Ό 적어주면 λœλ‹€.)

🀍 이미지 전솑 μ „

  • κΈ°μ‘΄ μž‘μ—… ν΄λ”μ˜ public/images μ—λŠ” μ•„λ¬΄λŸ° νŒŒμΌλ„ μ—†μ—ˆλ‹€.

🀍 이미지 전솑


🀍 이미지 전솑 ν›„

  • κΈ°μ‘΄ μž‘μ—… ν΄λ”μ˜ public/images 에 μ „μ†‘λœ profile.jpg κ°€ μ €μž₯된 것을 μ•Œ 수 μžˆλ‹€.

πŸ’œ μ—…λ‘œλ“œν•œ 이미지 보여주기 (이미지 API λ§Œλ“€κΈ°)

🀍 JavaScript 파일 μ½”λ“œ μž‘μ„±ν•˜κΈ°

app.get('/images/:img', function(req, res){
    res.sendFile(__dirname + '/public/images/' + req.params.img)
})
  • λˆ„κ΅°κ°€κ°€ /images/:νŒŒλΌλ―Έν„°λ‘œ GET μš”μ²­μ„ ν•˜λ©΄ /public/images/ λ‚΄μ—μ„œ :νŒŒλΌλ―Έν„°μ— ν•΄λ‹Ήν•˜λŠ” 이미지λ₯Ό 보내달라고 μž‘μ„±ν–ˆλ‹€.

🀍 μ‹€μ œ κ²½λ‘œμ—μ„œ 확인해보기

  • μ‹€μ œλ‘œ /images/profile.jpg 에 GET μš”μ²­μ„ 해보면 μ•„λž˜μ™€ 같이 λΈŒλΌμš°μ €μ— 이미지가 μ •μƒμ μœΌλ‘œ λ‚˜μ˜€λŠ” 것을 확인할 수 μžˆλ‹€.


🀍 νŠΉμ • νŽ˜μ΄μ§€μ— μ—…λ‘œλ“œν•œ 이미지 뢈러였기

  • λ‚˜λŠ” ν™ˆμœΌλ‘œ 이미지λ₯Ό λΆˆλŸ¬μ˜€λŠ” κ²ƒμœΌλ‘œ ν…ŒμŠ€νŠΈν•΄λ³΄μ•˜λ‹€.
<h4 class="container mt-5"><strong>ν™ˆ</strong></h4>
<div class="container mt-4 text-center">
  <img src="/images/profile.jpg" style="width: 80%">
</div>
  • ν™ˆνŽ˜μ΄μ§€ EJS νŒŒμΌμ— μœ„μ™€ 같이 img νƒœκ·Έλ₯Ό λ„£μ–΄μ£Όκ³  src λŠ” '/images/profile.jpg' 둜 λ„£μ–΄μ£Όμ—ˆλ‹€.

 

  • 그러면 ν™ˆνŽ˜μ΄μ§€μ—μ„œ μœ„μ™€ 같이 이미지가 λœ¨λŠ” 것을 확인할 수 μžˆλ‹€.
728x90
λ°˜μ‘ν˜•