[Express] 프로필 사진을 변경하려면..?
짧은 프로젝트를 진행하던 중, 대수롭지 않게 여겼던 기능 중 하나가 발목을 잡았습니다.
유저가 회원가입할 때, 유저의 프로필 사진을 클라이언트에서 업로드 받아 이를 저장하여 유저가 로그인할 때마다 그 프로필 사진을 보여주는 것이었습니다.
처음엔 클라이언트에서 그 이미지의 주소를 상태로 관리하는 것을 생각했으나, 다양한 유저의 프로필 사진을 보기 위해선 서버 또는 DB에 저장해야할 것 같다고 생각했습니다.
DB에 이미지 저장은 NO
이를 구현하기 위해 수많은 구글링을 한 결과, DB는 데이터를 저장하는 공간이 아니라, 데이터를 효과적으로 관리하고 다룰 수 있게 만든 도구임을 알게됐습니다.
이미지는 바이너리 파일로, DB에서 그 이미지의 파일 자체를 관리하게 된다면 DB의 성능 저하가 발생한다는 것을 알게됐습니다.
즉, DB에 파일을 저장하는 것이 아니라, DB에는 그 이미지의 경로(String)만 저장하는 것이 효과적이라는 것을 알게됐습니다.
그리고, 클라이언트로부터 업로드 받은 이미지는 서버에 저장하여 응답하는것이 효과적이라는 것을 알게됐습니다.
BLOB
처음 DB Schema를 기획할 땐 userPic
이란 테이블에 BLOB
타입을 줄 생각이었습니다.
Binary large object(BLOB)는 데이터베이스 관리 시스템의 하나의 엔티티로서 저장되는 이진 데이터의 모임입니다. BLOB은 일반적으로 그림, 오디오, 또는 기타 멀티미디어 오브젝트로 보통 이루어져 있습니다.
BLOB 타입은 이름마다 저장할 수 있는 용량이 제한되어 있습니다.
이름 | 용량 |
---|---|
TINYBLOB | maximum length of 255 bytes |
BLOB | maximum length of 65,535 bytes |
MEDIUMBLOB | maximum length of 16,777,215 bytes |
LONGBLOB | maximum length of 4,294,967,295 bytes |
유저마다 업로드하는 프로필 사진의 용량은 모두 제각각일 것이기 때문에, BLOB은 비효율적이라 생각하게 됐습니다.
또한, DB 용량 자체도 AWS RDS 로 배포할 것이기 때문에, 용량이 늘어나면 과금되는 부분도 영향을 미쳤습니다.
How to?
서두에 말한 것 처럼, 이미지 파일은 다른 저장 공간에 저장하고, MySQL DB에는 그 파일의 경로만 저장하기로 했습니다.
이를 위해, node.js
의 multer
모듈을 사용할 수 있었습니다.
Multer는 파일 업로드를 위해 사용되는 multipart/form-data 를 다루기 위한 node.js 의 미들웨어 입니다.
npm install --save multer
App.js
const express = require('express');
const imgRouter = require('./routes/img');
const app = express();
app.use('/', imgRouter);
app.listen(4000, () =>{
console.log('4000번 포트 서버');
})
routes/img.js
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const router = express.Router();
fs.readdir('uploads', (error) => {
// uploads 폴더 없으면 생성
if (error) {
fs.mkdirSync('uploads');
}
})
const upload = multer({
storage: multer.diskStorage({
destination(req, file, cb) {
cb(null, 'uploads/');
},
filename(req, file, cb) {
const ext = path.extname(file.originalname);
cb(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
limits: { fileSize: 5 * 1024 * 1024 },
})
// 이미지 업로드를 위한 API
// upload의 single 메서드는 하나의 이미지를 업로드할 때 사용
router.post('/upload', upload.single('img'), (req, res) => {
console.log(req.file);
res.json({ url : `/${req.file.filename}`});
})
module.exports = router;
Multer options
-
Storage
파일 저장 방식, 경로, 파일 명 설정- diskStorage : 이미지가 서버에 저장 되도록 함. destination 메소드로 저장 경로를 설정할 수 있습니다.
- filename : 예시에 따르면 기존 이름(originalname) + 업로드 날짜(Date.now()) + 기존 확장자(ext) 를 합쳐서 파일명을 만들 수 있는 메소드입니다.
-
Limit
최대 이미지 파일 용량 허용치입니다.- fieldSize : 필드값 사이즈 최대 값입니다. 기본값은 1mb입니다.
- fileSize : multipart 형식 폼에서 최대 파일 사이즈입니다.(bytes) 기본값은 무제한입니다.
사이즈 제한 옵션을 지정하면 DDOS 공격으로부터 사이트를 보호하는데 도움이 됩니다!
Author And Source
이 문제에 관하여([Express] 프로필 사진을 변경하려면..?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@shitaikoto/Express-Handle-IMG저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)