node.js로 이미지 파일 업로드하고 불러오기

윤지섭·2022년 12월 18일
0

node.js랑 express를 공부하고 리액트와 함께 미니 프로젝트 진행하고 돌아왔습니다.

그 중에서 제일 어떻게하는지 헤맸던 이미지 파일을 업로드하고 불러오는 과정입니다...
정말 도움을 많이 받은 참고한 블로그

npm install --save multer

먼저 multer 모듈을 다운받아 줍시다

const db = require("./models");
const { Image } = db;
const multer = require("multer");

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "upload/"); // cb 콜백함수를 통해 전송된 파일 저장 디렉토리 설정
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname); // cb 콜백함수를 통해 전송된 파일 이름 설정
  },
});

var upload = multer({ storage });
app.use("/image", express.static("upload"));
//파일에 접근하기 디렉토리 경로 설정 /image 경로를 통해 upload폴더에 접근 할수있다

app.post("/api/images", upload.single("imageFile"), async (req, res) => {
  //	imageFile의 이름으로 들어온 파일을 req.file에 받아온다
  console.log(req.file);
  const newInfo = req.body;
  if (req.file) {
    const filePath = "http://localhost:3000/image/" + req.file.originalname;
    //파일이미지를 불러오기위한 경로+이미지파일 이름

    newInfo["imageFile"] = filePath;
    //경로를 request의 json파일에 넣어 수정 해준다
  }
  const member = Member.build(newInfo);
  await member.save();
});

app.get("/api/images/:id", async (req, res) => {
  //아이디의 이미지를 찾음
  const { id } = req.params; //:id자리에 올 값을 받아온다
  const member = await Member.findOne({ where: { id } });
  res.send(member);
});

app.js파일의 내용

파일을 업로드하기 위한 사전작업과 파일 이미지를 불러오기 위한 이미지의 src를 만드는 작업입니다.
참고로 console.log로 request를 통해 들어온 file을 찍어보면

{
[0] fieldname: 'imageUrl',
[0] originalname: 'IMG_3852.jpg',
[0] encoding: '7bit',
[0] mimetype: 'image/jpeg',
[0] destination: 'upload/',
[0] filename: 'IMG_3852.jpg',
[0] path: 'upload\IMG_3852.jpg',
[0] size: 55639
[0] }

이런식으로 찍혀서 file의 이름을 originalname으로 받아오는겁니다

import { useRef, useState } from "react";

export async function imageUpload(formData) {
  await fetch(`http://localhost:3000/api/images`, {
    method: "POST",
    body: formData,
  });
}

function Image() {
  const inputRef = useRef();
  const [imageFile, setImageFile] = useState(null);
  console.log(imageFile);

  const handleChange = (e) => {
    const nextValue = e.target.files[0];
    setImageFile(nextValue);
  };

  const uploadImage = async () => {
    const formData = new FormData();
    formData.append("imageFile", imageFile);
    //이미지 파일을 formData로 json 형태로 만들어 전송하자
    await imageUpload(formData);
    //api
  };

  return (
    <>
      <form action="/" onSubmit={uploadImage} enctype="multipart/form-data">
        <input
          type="file"
          accept="image/*"
          onChange={handleChange}
          ref={inputRef}
          id="fileInput"
        />
        <button type="submit">업로드</button>
      </form>
    </>
  );
}

export default Image;

리액트 내에서 node.js를 통해 데이터를 보내기 위한 코드


이를 통해 업로드하면

이렇게 서버의 upload폴더에 저장이 됩니다


제 db엔 back.png가 2번 id로 들어가있네요

 


자 이제 이미지 파일을 업로드하고 해당 이미지의 경로를 저장했으니 불러오도록 합시다

import { useState } from "react";

export async function getImage(id) {
  const res = await fetch(`http://localhost:3000/api/images/${id}`);
  const body = await res.json();

  return body;
}

function ImageShow() {
  const [imageShow, setImageShow] = useState(null);

  const loadImage = async () => {
    const imageInfo = await getImage(2);
    //처음 넣은 이미지의 아이디 1번

    setImageShow(imageInfo.imageFile);
  };

  return (
    <>
      <img src={imageShow} alt="이미지를 불러와야 합니다" />
      <button onClick={loadImage}>불러오기</button>
    </>
  );
}

export default ImageShow;

버튼을 클릭하면 이미지 경로를 불러와 이미지의 src로 만들어주면 서버의 이미지를 불러올 수 있다.

profile
개발자를 꿈꾸는 사람

0개의 댓글