[NodeJS] Upload Image in Local Server

이애진·2022년 7월 14일

Node

목록 보기
8/12
post-thumbnail

install module

npm install multer sharp @types/multer @types/sharp
  • multer는 파일을 업로드 하기 위한 node.js 미들웨어이다
  • node.js에서 이미지를 처리하기 좋은 패키지이다

Create a folder to store images

import multer from 'multer';
import { mkdirSync, existsSync, writeFile } from 'fs';
import { join } from 'path';
import sharp from 'sharp';

const dir = join(__dirname, "..", "public", "images", "uploads");

const _storage = multer.diskStorage({
    destination: (req, file, callback) => {
        if (!existsSync(dir)) {
            mkdirSync(dir, { recursive: true });
        }

        callback(null, dir);
    },
    filename: (req, file, callback) => {
      callback(null, Date.now().valueOf() + "_" + file.originalname);
    }
});

const upload = multer({ storage: _storage }); // upload 미들웨어

원하는 경로가 존재하지 않는다면 새로 폴더를 생성한다 recursive 속성을 사용하면 상위 폴더까지 생성할 수 있다
파일이름도 중복 문제가 있을 수 있기 때문에 Date.now 와 함께 쓴다
여기서 upload는 파일 업로드를 받을 수 있는 객체가 된다


Create Router

registerRouter.post('/',  upload.single('profile'), (req: Request, res: Response, next: NextFunction) => {
    try {
        sharp(req.file?.path) // 압축할 이미지 경로
            .resize({ width: 600 }) // 비율을 유지하며 가로 크기 줄이기
            .withMetadata() // 이미지의 exif 데이터 유지
            .toBuffer((err, buffer) => {
                if (err) next(err);

                writeFile(req.file?.path!, buffer, (e) => {
                    if (e) next(e);
                });
            });

        res.json({ filename: `${req.file?.filename}`});
    } catch (error) {
        next(error);
    }
});

사용자로부터 post 요청을 받으면 upload.single(’profile’)이 실행된다

upload.single(’profile’) 는 요청받은 파일을 위에서 설정한 위치에 저장함과 동시에 req 객체에 file이라는 속성을 추가해서 관련 정보를 저장한다

이 때 profile은 front input name 속성이다

sharp로 이미지 리사이즈 해서 파일크기 압축효과를 얻을 수 있다
이미지 크기가 크면 이미지 로딩 시간이 길어질 수도 있기 때문에 압축한다

압축 후 writeFile을 통해 이미지를 저장해주면 기존 파일을 덮어씌우기 때문에 기존 파일을 삭제할 필요도 없고 충돌로 인한 오류도 나지 않는다


Create Pug

doctype html
html
    head
        meta(charset="utf-8")
        title Bookitory

    body
        h2 Register

        form(action="/register" method="post" id="register" enctype="multipart/form-data")
            input(type="text" name="email" placeholder="email" autofocus)
            br
            input(type="password" name="password" placeholder="password")
            br
            input(type="file" name="profile" accept="image/png,image/jpg,image/jpeg")
            br
            button submit

    script(type="text/javascript", src="/scripts/register/index.js")

image를 업로드 하기 위해 form enctype을 multipart/form-data로 지정해야한다

profile
Frontend Developer

0개의 댓글