REturn 0;

이미지 업로드 및 폼 데이터로 전송하기 본문

해커톤

이미지 업로드 및 폼 데이터로 전송하기

zza.___.lng 2023. 9. 10. 15:20

해커톤 프로젝트를 진행하면서 역할을 분담해서 했더니 팀 프로젝트 코드인데 내가 모르는 코드가 몇개 있는 것 같아서 공부해서 이해하고 넘어가야된다는 생각이 들었다.

 

+ 게시글에는 보통 이미지를 첨부할 수 있게 하기 때문에 알아두면 좋겠다는 생각이 들어서 프로젝트에 팀원이 작성한 코드로 공부를 해보았다.

 

const insertImg = (e) => {
    let reader = new FileReader();
    // 업로드 파일 세팅 부분
    const file = e.target.files[0];
    setUploadedImage(file);

    // 프리뷰 이미지 세팅 부분
    if (e.target.files[0]) {
      reader.readAsDataURL(e.target.files[0]);
    } else {
      setPreviewImg("/img/previewDefalut.svg"); // 파일 선택 취소 시 프리뷰 이미지 삭제
    }

    reader.onloadend = () => {
      const previewImgUrl = reader.result;

      if (previewImgUrl) {
        setPreviewImg(previewImgUrl);
      }
    };
  };

 

FileReader를 이용해 파일 입출력 하는건 처음이라 공부를 좀 해봤는데, 이 글이 제일 정리가 잘 되어있는 것 같아서 공유합니당

 

[JavaScript] 파일 입출력 (FileReader)

type이 file인 input태그 <input type="file" /> 또는 API 요청과 같은 File 또는 Blob 객체를 편리하게 처리할 수 있는 방법을 제공하는 객체abort, load, error와 같은 이벤트에서 발생한 프로세스를 처리하는데

velog.io

 

let reader = new FileReader();

setUploadedImage(e.target.files[0]);
console.log(e.target.files[0]);

생성자 함수를 이용해 FileReader 객체(파일을 읽어오는 역할)를 생성하여 reader 변수에 할당한다.

e.target.files[0]은 파일을 입력받는 input에서 선택한 파일을 나타내는데, 이를 useState상태 변수인 setUploadedImage(e.target.files[0])를 이용해 uploadedImage에 설정하여 폼 제출 시 이미지를 서버로 보낼 수 있도록 한다. 콘솔 창을 보면 아래와 같이 이미지의 정보가 나온다.

 

if (e.target.files[0]) {
  reader.readAsDataURL(e.target.files[0]);
} else {
  setPreviewImg("/img/previewDefalut.svg");
}

e.target.files[0]가 존재하는지 확인하고 true면 readAsDataURL 메서드를 이용해 선택한 파일을 데이터 URL로 변환한다.

이 데이터 URL은 미리보기 이미지로 사용된다. false면 기본 미리보기 이미지를 출력한다.

 

reader.onloadend = () => {
  const previewImgUrl = reader.result;
  console.log(previewImgUrl);
  
  if (previewImgUrl) {
    setPreviewImg(previewImgUrl);
  }
};

 

FileReader의 onloadend 메서드는 파일 읽기가 끝나고 난 후에 실행되는 함수이다.

result 메서드를 이용해 선택한 이미지 파일의 데이터 url을 저장하고, 저장에 성공하면 previewImg 변수에 데이터를 setPreviewImg(previewImgUrl);을 이용해 저장한다.

저장에 실패했을 경우를 대비하여 성공했을 때 저장하는 방식을 사용한 것 같다.

콘솔 창을 보면 아래와 같은 정보가 출력되는데,,, 이게 이미지 파일의 데이터 url인가보다.

 

 


이미지를 첨부했으면 이제 폼 데이터로 변환하여 서버에 전송을 해야한다.

const handleSubmit = (event) => {
    event.preventDefault();
    const userConfirmed = window.confirm("게시글을 업로드 하시겠습니까?");
    if (userConfirmed) {
      const formData = new FormData();
      if (uploadedImage != null) {
        formData.append("image", uploadedImage);
      }
      formData.append("writer", 3);
      formData.append("title", title);
      formData.append("content", content);

      postNewTip(formData);
      alert("업로드 완료!");
    }
};

 

FormData는 처음 봐서 공부를 좀 해봤는데, 이 글이 제일 정리가 잘 되어있는 것 같아서 공유합니당

 

🌐 FormData 사용법 & 응용 총정리 (+ fetch 전송)

FormData API 보통 서버에 데이터를 전송하기 위해서는 HTML5 의 폼 태그를 사용해 다음과 같이 메뉴를 구성하여 제출 해본 기억들이 있을 것이다. 아이디 비밀번호 성별 남자 여자 응시분야 영어 수

inpa.tistory.com

 

event.preventDefault();
const userConfirmed = window.confirm("게시글을 업로드 하시겠습니까?");
  • submit 기본 동작을 없애고, 게시글을 업로드할지 확인하는 알림을 띄운다.
    if (userConfirmed) {
      const formData = new FormData(); //새로운 폼 객체 생성
      if (uploadedImage != null) { // 앞서 작성한 코드를 통해 이미지를 불러왔으면
        formData.append("image", uploadedImage); // 이미지 데이터 추가
      }
      formData.append("writer", 3); // 폼 데이터 추가
      formData.append("title", title); // <input name="title" value={title}/>과 같다!
      formData.append("content", content); // 동일
    }
  • new FormData()를 이용해 새로운 Form 객체를 생성하고 객체 안에 작성자, 제목, 내용을 데이터로 넣어준다.
postNewTip(formData); // API에 formData를 넣어서 호출
alert("업로드 완료!");
  • 데이터를 추가하여 만든 formData를 api의 body부분에 할당하여 전송하면 끝!

 


 

<>	  
  <ImgSection>
    <PreviewImg src={previewImg} />
    <ImgLabel htmlFor="imageInput">이미지 업로드</ImgLabel>
    <ImgInput
      type="file"
      accept="image/*"
      id="imageInput"
      onChange={(e) => insertImg(e)}
    />
  </ImgSection>
  <SubmitBtn onClick={handleSubmit} type="submit">
    게시글 업로드
  </SubmitBtn>
</>

<ImgInput> 컴포넌트에 accept는 모든 이미지 파일을 넣을 수 있게 해주는 코드이다.

"image/jpeg", "image/png"등으로 원하는 형식만 설정할 수도 있다.

컴포넌트를 위 코드와 같이 설정해주면

 

아래와 같이 이미지를 불러오는 칸과 게시글을 업로드하는 버튼이 생기고, 이미지를 업로드하면

본인이 선택한 이미지를 확인할 수 있게 미리보기가 잘 뜨는 것을 확인할 수 있다.

게시글 업로드 버튼을 누르면 폼데이터를 서버에 전송되는 것도 확인하였다.

 

 

어려운 코드인데 잘 만들어준 우리 팀원한테 박수👏🏻👏🏻👏🏻👏🏻