[node] 이미지 로딩 및 처리

Edward Hyun·2022년 4월 1일
0

backend

목록 보기
46/120

#0 고려 사항

웹에서 파일 업로드는 두 가지 방식이 있다.
(1) applecation/x-www-urlencoded
(2) multipart/form-data
전자의 경우 인코딩으로 인한 성능 이슈가 발생할수 있으니 후자의 방법으로 전송하는 것이 좋다고 한다.

DB에 이미지 저장 방법 2가지
(1) blob type으로 저장한다.
(2) 이미지 파일을 별도 폴더에 저장하고 경로명을 문자열 type으로 저장한다.

여기서는 (2) 이미지 파일을 별도 폴더에 저장하는 방법으로 진행한다. (먼저는 프로젝트 폴더 내 /uploads 폴더에 넣어보다. 배포시에는 우분투 서버내 지정된 폴더에 넣는 방법을 진행한다.)

html의 form 데이터로 이미지를 불러오는 경우
multer라는 모듈을 이용하여 파일을 받아온다.
(multer 옵셥에서는 이미지를 파일(DiskStorage)로 받거나 메모리(MemoryStorage)로 받는 경우를 설정할 수 있다.)

#1 multer 모듈

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

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

const app = express()

app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req.file is the `avatar` file
  // req.body will hold the text fields, if there were any
})

app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
  // req.files is array of `photos` files
  // req.body will contain the text fields, if there were any
})

const cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
  // req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
  //
  // e.g.
  //  req.files['avatar'][0] -> File
  //  req.files['gallery'] -> Array
  //
  // req.body will contain the text fields, if there were any
})
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, '/tmp/my-uploads')
  },
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
    cb(null, file.fieldname + '-' + uniqueSuffix)
  }
})

const upload = multer({ storage: storage })

upload = multer({storage}) 이 부분이 저장되는 함수라 보여진다. 이 것을 app.post()부분에서 호출해 줌으로 처리 되는듯하다.

아래 upload = multer({dest:...} 를 보면 여기는 경로만 지정해서 저장하는 방법이다. 이렇게 되면 파일이 ce243370b74107493fea0743d249a176 처럼 이상한 이름으로 확장자도 붙어 있지 않을 수 있다. 보안상 의도된 것으로 보인다.
storage 속성을 사용해서 파일명과 확장자를 사용할 수 있다.

const multer = require("multer");

const handleError = (err, res) => {
  res
    .status(500)
    .contentType("text/plain")
    .end("Oops! Something went wrong!");
};

const upload = multer({
  dest: "/path/to/temporary/directory/to/store/uploaded/files"
  // you might also want to set some limits: https://github.com/expressjs/multer#limits
});


app.post(
  "/upload",
  upload.single("file" /* name attribute of <file> element in your form */),
  (req, res) => {
    const tempPath = req.file.path;
    const targetPath = path.join(__dirname, "./uploads/image.png");

    if (path.extname(req.file.originalname).toLowerCase() === ".png") {
      fs.rename(tempPath, targetPath, err => {
        if (err) return handleError(err, res);

        res
          .status(200)
          .contentType("text/plain")
          .end("File uploaded!");
      });
    } else {
      fs.unlink(tempPath, err => {
        if (err) return handleError(err, res);

        res
          .status(403)
          .contentType("text/plain")
          .end("Only .png files are allowed!");
      });
    }
  }
);

#2 html에서 form

<form action="/profile" method="post" enctype="multipart/form-data">
  <input type="file" name="avatar" />
</form>

#3 node에서 multer 로직

#4 node에서 api 라우팅

#5 postman 이용한 테스트

#6 배포시 지정 이미지 폴더 사용하기

참고 ::
https://www.npmjs.com/package/multer
https://intrepidgeeks.com/tutorial/node-upload-and-delete-js-images
https://velog.io/@juhyun5060/node.js-multer-sharp
https://blog.daum.net/creazier/15310525
https://eastflag.co.kr/fullstack/rest-with-nodejs/node-rest_image/
https://www.zerocho.com/category/NodeJS/post/5950a6c4f7934c001894ea83
https://handhand.tistory.com/110

좀 독특한 사이트 = 노드로 스트리밍 서버 구현
https://javafa.gitbooks.io/nodejs_server_basic/content/chapter11.html

profile
앱&웹개발(flutter, vuejs, typescript, react), 인공지능(nlp, asr, rl), 백엔드(nodejs, flask, golang, grpc, webrtc, aws, msa, nft, spring cloud, nest.js), 함수형 프로그래밍(scala, erlang)을 공부하며 정리합니다.

0개의 댓글