Axios로 formData() 이용해 file 올리기(이미지 업로드)

wony·2022년 10월 14일
4

이미지 업로드 테스트를 하던 도중 발생했던 오류를 해결한 기쁜맘에 오랜만에 블로그에 글을 쓴다!

현재 나는 회사 s3 서버에 이미지 업로드 테스트를 진행중이었고 multipart/form-data 형태로 파일을 넘겨주어야 했기 때문에 여러 시도를 해본 끝에 해결하였다

✏️ form data 로 file 전송하기

<form
  encType="multipart/form-data"
  method="post"
  action=`${url주소}/upload_multer_multi`
>
  <input type="file" name="userfile" multiple />
  <input type="submit" />
</form> 

충격 그차체 였던 방식

post 요청할때 파라미터로 값을 넣어주지 않아도 알아서 요청이 가는것을 보며 충격을 받았던 방법이다
file만 요청을 보내는 경우에는 너무 유용하게 쓰일 방법이다

하지만 나는 앞으로 프로젝트를 진행하다보면 form 안에 파일 말고도 다른 값들을 넣어 보내야하는 경우가 많아지기 때문에 함수로 분리를 시도했다

✏️ 함수로 분리하여 form data 전송하기

import axios from "axios";
import React, { ChangeEvent, FormEvent, useState } from "react";

export default function FileUpload() {
  const [files, setFiles] = useState<FileList | undefined>();

  const onChangeFiles = (e: ChangeEvent<HTMLInputElement>) => {
    const fileList = e.target.files;
    if (fileList !== null) {
      setFiles(fileList);
    }
  };
  

  const upload = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData();
    // @ts-ignore
    Array.from(files).forEach((el) => {
      formData.append("userfile", el);
    });

    try {
      const response = await axios.post(`/upload_multer_multi`, formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
        transformRequest: [
          function () {
            return formData;
          },
        ],
      });
      alert("성공");
    } catch (error) {
      alert("돌아가");
      console.log(error);
    }
  };

  return (
    <div>
      <form
        onSubmit={upload}
        encType="multipart/form-data"
      >
        <input type="file" name="userfile" multiple onChange={onChangeFiles} />
        <input type="submit" />
      </form>
    </div>
  );
}

이 코드를 위해 하루를 고생했던가,,,
CORS 에러도해결했고
데이터도 무사히 전송된다!!

가장 중요했던 부분은 이부분이다

// 수정 전
files.forEach((el) => {
      formData.append("userfile", el);
    });

// 수정 후
 Array.from(files).forEach((el) => {
      formData.append("userfile", el);
    });

files를 console에 찍어보면 배열인척하는 객체더라,,

그래서 그런가 foreach를 썼더니 자꾸 에러가 났다ㅠㅠ
사수님이 알려주신 블로그에서 답을 얻고 MDN을 찾아보니

FileList가 유사배열 객체 인가보다,,,,
아니면 댓글로 알려주세요,,,

그래도 이렇게 해결해서 얼마나 다행인지!!

✏️ formData console에서 확인하기

이 기능을 구현하면서 formData를 아무리 console에 찍어도

이렇게 보이는게 아닌가,,,
구글링 해보니!!

    // FormData의 key 확인
    // @ts-ignore
    for (const key of formData.keys()) {
      console.log(key);
    }
    // FormData의 value 확인
    // @ts-ignore
    for (const value of formData.values()) {
      console.log(value);
    }
    console.log(formData);

이렇게 써주면

아주 잘 보인다

이번 이미지 업로드를 통해 배운게 너무 많아서 블로그를 안쓸 수가 없었다
크 성장한 나 뿌듯!


참고
https://surajsharma.net/blog/react-upload-file-using-axios
https://okky.kr/articles/1076897
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/from

profile
무럭무럭 성장중🌿

0개의 댓글