멀티 이미지 업로드 기능 구현하기

JIHUN_K·2023년 11월 1일
0


[진행중인 사이드 프로젝트 UI]

개요

멀티 이미지 업로드 기능은 여러 개의 이미지 파일을 업로드할 수 있는 기능이다.

이미지 업로드 과정

  • 프론트에서 멀티 사진 업로드 기능을 구현할 때는 먼저 사용자가 여러 이미지를 선택할 수 있는 파일 선택 창을 제공.
  • 선택한 파일은 브라우저에서 미리 볼 수 있는 형태로 표시.
  • 선택한 파일은 FormData 객체를 사용하여 백엔드로 전송.

프론트엔드에서 구현해야할 요소들

업로드 및 제거

한번에 여러 사진을 동시에 업데이트 할 수 있어야하고 또한 한개씩 추가될수도 있어야 한다.

미리보기

이미지 미리보기를 위해 이미지 파일을 이용해 이미지를 로드해야한다. 하지만 File 객체를 그대로 사용은 불가능하다. img src에 적합하게 해당 객체를 가리키는 URL로 변환이 필요하다.

URL.createObjectURL() 메소드는 주어진 객체를 가리키는 URL을 DOMString으로 변환하는 기능을 한다. 해당 url은 window 창이 사라지면 함께 사라진다.

   const url = URL.createObjectURL(file) 
   //url blob:http://localhost:5173/28ff8746-94eb-4dbe-9d6c-2443b581dd30

파일 전송

FormData 객체를 생성해 선택한 파일들을 서버로 전송하는법을 선택해야 한다.

FormData 객체는 웹 애플리케이션에서 파일 전송을 위해 사용되는 중요한 도구인데 일반적인 JSON 데이터 전송과는 달리 파일 전송에 특화되어 있어 이를 통해 파일과 키-값 쌍을 쉽게 생성하고 전송할 수 있다
HTTP 전송하기위해서는 파일 타입을 multipart/form-data을 설정해야한다.

const formData = new FormData();
formData.append('file', file);

const requestOptions = {
  method: 'POST',
  headers: {
    // 여기서 Content-Type을 설정.
    // boundary는 FormData 객체가 자동으로 생성.
    'Content-Type': 'multipart/form-data',
  },
  body: formData,
};

파일 이어붙이기

  const 리뷰이미지파일업로드 = event => {
    const target = event.target
    const file = target.files[0]
    const url = URL.createObjectURL(file)
    if (file) {
      setFormValues({
        ...formValues,
        ['files']: [url, ...formValues.files.slice(0, 4)],
      })
      return
    }
  }

파일 유형

이미지 파일 크기는 어디까지 제한할것인지 어떤 확장자를 필요한지를 결정해야한다.

어떤 확장자를 선택해야할까?

특성JPEGPNG
압축손실 압축, 이미지 품질 감소 가능비손실 압축, 원본 이미지 품질 유지
투명도지원하지 않음지원
색상16 백만 색상, 압축으로 일부 색상 손실16 백만 색상, 색상 손실 없음
용도사진이나 복잡한 이미지로고, 아이콘, 이미지 투명도 필요
파일 크기작을 수 있음대형 파일 크기
웹 성능페이지 로딩 시간 감소페이지 로딩 시간 증가

이미지를 업로드하고 최적화하기 위해 대부분의 웹 사이트에서는 JPEG와 PNG 확장자를 주로 사용한다.

JPEG(JPG): JPEG는 사진이나 복잡한 이미지에 적합한 압축 형식이다. 일반적으로 사진이나 컬러 이미지에 사용되며, 압축률을 높일 수 있어 파일 크기를 줄이면서도 이미지 품질을 유지할 수 있다.

PNG: PNG는 투명도와 고해상도 이미지에 적합한 형식이다. 압축률이 높은 이미지에는 적합하지 않지만, 로고나 아이콘 등에 자주 사용된다.또한 손실이 없는 이미지 포맷으로 원본 이미지의 품질을 유지할 수 있다.

const allowedExtensions = /(\.jpg|\.jpeg|\.png|\.gif)$/i;

const 리뷰이미지파일업로드 = (event) => {
  const file = event.target.files[0];
  if (!allowedExtensions.exec(file.name)) {
    alert('허용되지 않는 파일 형식입니다. jpg, jpeg, png, gif 파일만 허용됩니다.');
    event.target.value = '';
    return false;
  }
  // 파일 확장자가 허용되는 경우 추가 로직 수행
};

파일 크기 제한

파일크기를 제한해야하는 이유

서버 측클라이언트 측
영향서버 리소스 및 용량 사용량 증가네트워크 대역폭 소모 및 장치 성능 저하
문제점- 서버 부하 증가- 파일 업로드 시 네트워크 속도 감소
- 파일 시스템 공간 소모- 장치에 저장된 용량을 초과할 경우 문제 발생
- 서버 장애 가능성- 사용자 경험 저하
- 장치 성능 저하
해결 방안- 파일 크기 제한 설정- 파일 크기 제한 설정
- 파일 업로드 속도 제한
- 용량 소모를 최적화하는 방법 도입

파일크기는 어느정도?

이것은 정답은 없는 것 같다. 각자 서비스 규모에 제한하면 되는 것 같다.
현재 우리 팀 같은 경우는 서버 비용 부담도 있어 사진 1개당 1MB로 제한했다

파일크기를 제한하는 법


<input
  type="file"
  id="file"
  name="file"
  accept=".jpg, .png"
  onChange={(e) => handleFileUpload(e)}
/>

const 리뷰이미지파일업로드 = (event) => {
  const file = event.target.files[0];
  const fileSizeLimit = 5 * 1024 * 1024; // 5MB로 파일 크기 제한

  if (file && file.size <= fileSizeLimit) {
    // 파일 업로드 처리
  } else {
    // 파일 크기 초과 경고 메시지
  }
};

최종

  const 리뷰이미지업로드 = event => {
    const target = event.target
    const file = target.files[0]
    const fileSizeLimit = 1 * 1024 * 1024
    const url = URL.createObjectURL(file)
    if (file && file.size <= fileSizeLimit) {
      setFormValues({
        ...formValues,
        ['files']: [url, ...formValues.files.slice(0, 4)],
      })
      return
    } else {
      alert('1MB 이하의 이미지만 올려주세요')
    }
  }

추가로 보안 및 성능 고려 사항

멀티 사진 업로드 기능을 구현할 때 보안과 성능에 대한 고려가 필요하다. 사용자가 업로드한 파일을 검사하여 악성 파일이 포함되어 있는지 확인하고, 서버의 부하를 최소화하기 위해 파일 업로드 및 다운로드 시에 최적화된 방법을 사용해야한다.

참고자료

profile
한발 한발 내딛자

0개의 댓글