[React] 이미지 파일 업로드 express 서버 송신

2021. 8. 2. 19:18React

React Code

const BASE_URL = "http://localhost:3001";

const Mypage = () => {

    const [content, setContent] = useState("");
    const [uploadedImg, setUploadedImg] = useState({
        fileName: "",
        fillPath: ""
    });
    
    const fileAdd = () => {
      let file = document.getElementById('fileAdd');
      file.click();
    }
    
    const onChange = (e) => {
        setContent(e.target.files[0]);
    };

    const onSubmit = (e) => {
        e.preventDefault();
        const formData = new FormData();
        formData.append("img", content);
        axios
            .post("http://localhost:3001/upload", formData)
            .then(res => {
                const { fileName } = res.data;
                console.log(fileName);
                setUploadedImg({ fileName });
                alert("The file is successfully uploaded");
            })
            .catch(err => {
                console.error(err);
            });
    };
    return (
    <>
    <form onSubmit={onSubmit}>
    	<div onClick={fileAdd} id="uploadDiv">
          <input
          id="fileAdd"
          style={{ display: 'none' }}
          type="file"
          onChange={onChange}
          />
        </div>
        <button type="submit">Upload</button>
   </form>
   </>
    )
}

 

express Server

 

먼저 필요한 라이브러리를 다운 받습니다.

yarn add express multer

multer 라이브러리는 프론트로부터 받은 파일에 대한 처리를 할 수 있도록 도와줍니다.

 

const path = require("path");
const express = require("express");
const app = express();
const multer = require("multer");
const PORT = 4000;
app.use(express.static("public"));
const storage = multer.diskStorage({
  destination: "./public/img/",
  filename: function(req, file, cb) {
    cb(null, "imgfile" + Date.now() + path.extname(file.originalname));
  }
});

먼저 Storage를 작성합니다. destination 옵션은 받아온 이미지를 어디에 저장할 것인지 정합니다. 만약 이러한 폴더가 없다면 multer가 이미지를 받아올때 자동으로 생성합니다.

cb는 콜백의 줄임말인데 이 부분을 통하여 이미지의 이름을 정해줍니다. 타임스탬프와 파일의 확장자명을 정해서 저장할 수 있도록 해줍니다. 이렇게 하지 않으면 같은 이름의 파일이 저장되는 경우 버그가 생깁니다.

이 방법은 로컬 서버 폴더에 이미지를 저장하게 되는데 AWS S3 Bucket 등으로 이미지 데이터를 클라우드 서버에 보관할 수 있습니다. 그 경우 이 Storage 코드를 다르게 작성해줍니다.

const upload = multer({
  storage: storage,
  limits: { fileSize: 1000000 }
});

다음은 업로드 옵션입니다. 어떤 storage를 사용할 것인지(로컬 또는 클라우드) 그리고 파일의 사이즈를 정합니다. 단위는 byte입니다.

app.post("/upload", upload.single("img"), function(req, res, next) {
  res.send({
    fileName: req.file.filename
  });
});

이제 프론트의 axios로부터 post 요청을 받을 코드를 작성합니다. 프론트에서 formData에서 정해주었던 이름으로 img를 받습니다. 그리고 Storage 옵션에서 정해준 fileName을 다시 프론트로 보내줍니다.

'React' 카테고리의 다른 글

[React] 환경변수 사용하기  (0) 2021.10.25
[React] i18n 다국어 지원하기  (0) 2021.09.08
[React] 소셜 로그인 API  (0) 2021.07.06
[React] useHistory  (0) 2021.07.01
[React] React Query 사용하기  (0) 2021.07.01