[FrontEnd] 파일 전달받는 BackEnd에 fetch 하는 과정

코딩기록·2025년 1월 1일

[ 파일 드롭 이벤트 로 파일 받기 ]

코드 설명

  • 이벤트 종류 : dropover, dropleave, drop
  • 파일이 드롭되었을 때 파일 가져오는 법 : drop이벤트 발생 시 event.dataTransfer.files에 파일 전달됨

코드

// 파일 드래그& 드롭 이벤트
    // 드래그 영역에 진입했을 때
    $uploadArea.addEventListener('dragover', (e) => {
        e.preventDefault();
        $uploadArea.classList.add('dragover');
    });

    // 드래그 영역에서 나갔을 때
    $uploadArea.addEventListener('dragleave', (e) => {
        e.preventDefault();
        $uploadArea.classList.remove('dragover');
    });

    // 드래그 영역에 드롭했을 때
    $uploadArea.addEventListener('drop', (e) => {
        e.preventDefault(); // 드롭했을 때 이미지 새탭이 열리거나 파일이 다운로드되는 것을 방지

        // 파일 정보 얻어오기 : event 객체의 dataTransfer.files()
        const files = [...e.dataTransfer.files];
        // 파일 검증
        if (files.length > 0) handleFiles(files);
    });






[ Input[type="file"] 태그로 로 파일 받기 ]

input[type="file"]로 받은 파일을 검증하는 방법

- 코드 설명

  • input[type="file"]에 파일을 선택하면 change 이벤트가 발생하고, 이 때 e.target.files에 파일이 전달됨

- HTML

<!-- 파일 입력 요소 -->
<input type="file" id="fileInput" multiple />

<!-- 이미지 미리보기용 요소 -->
<img id="preview" alt="Image Preview" style="max-width: 200px; display: none;" />

- 코드

// 허용되는 MIME 타입
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];

// 허용되는 파일 확장자
const allowedExtensions = ['jpg', 'png', 'pdf'];

// 허용되는 최대 파일 크기 (5MB)
const maxSize = 5 * 1024 * 1024; 

// 허용되는 최대 파일 개수
const maxFiles = 5; 

// 파일 입력 요소 및 미리보기 이미지 요소
const fileInput = document.querySelector('#fileInput');
const preview = document.querySelector('#preview');

// 파일 입력 이벤트 리스너 추가 :
// :   input[type=file]의 change 이벤트가 발생하면
//     e.target.files 객체와 관련 정보 전달됨
fileInput.addEventListener('change', (event) => {
    const files = event.target.files; // 선택된 파일 리스트

    // (1) 파일 개수 검증
    if (files.length > maxFiles) {
        console.error('Too many files selected'); // 오류 메시지 출력
        return; // 검증 실패 시 종료
    }

    // (2) 선택된 파일들 반복 검증
    Array.from(files).forEach((file) => {
        // (2-1) 파일 유형 검증
        if (!allowedTypes.includes(file.type)) {
            console.error(`${file.name} has an invalid type`); // 잘못된 파일 유형 경고
            return; // 검증 실패 시 종료
        }

        // (2-2) 파일 크기 검증
        if (file.size > maxSize) {
            console.error(`${file.name} is too large`); // 파일 크기 초과 경고
            return; // 검증 실패 시 종료
        }

        // (2-3) 파일 확장자 검증
        const fileExtension = file.name.split('.').pop().toLowerCase(); // 파일 확장자 추출
        if (!allowedExtensions.includes(fileExtension)) {
            console.error(`${file.name} has an invalid extension`); // 잘못된 확장자 경고
            return; // 검증 실패 시 종료
        }

        // 검증 통과 메시지
        console.log(`${file.name} is valid`);

        // (3) 이미지 미리보기
        if (file.type.startsWith('image/')) { // startswith로 파일이 이미지인지 확인
            const reader = new FileReader(); // FileReader 객체 생성
            reader.onload = (e) => {
                preview.src = e.target.result; // 이미지 URL 설정
                preview.style.display = 'block'; // 이미지 요소 표시
            };
            reader.readAsDataURL(file); // 이미지 파일을 읽어 데이터 URL로 변환
        }
    });
});






[ 파일 fetch 하기 : formdata ]

- 코드 설명

  • 파일을 fetch 할 때는,
    1) 파일(파일+json을 보낼 경우는 json도)을 FormData로 만들어 준 후,
    2) fetch의 body를 FormData로 설정해준다.fetch의 body에 FormData를 보내준다.

  • 검색용 : formData, append, blob

- 코드

// 1. formdata를 생성하여
const formData = new Formadata();

//2. formdata 안에 보내려는 데이터를 apped 해준다

  // -  json 객체라면 아래 형식으로 append
  //  : formData.append(key, key value, {data type})
  //  : 이 때, key value는 1) json으로 만들어 준 후 2) 대용량이므로 Blob 객체로 변환해줌
  formData.append(key name, new Blob([JSON.stringify(feedData)], {
    type: 'application/json'
  }));

  // - 파일이라면 아래 형식으로 append
  //  : formData.append(key, key value)
  //  :  이 때, 파일을 한 번에 여러 파일 못 보내므로 반복문으로 돌려준다.
  imageFiles.forEach(file => {
     formData.append('images', file);
  });

  // 3. 서버에 전송 요청
  // - 보통 Post FETCH 할 때 fetch(url, {method:, headers: {'content-type': $$$$}, body: } 
  // 이런 식으로 headers에 content-type을 넣어서 보내지만,
  // 이 경우에는 위에 2번에서 content-type 정의했으므로 fetch 할 때는 생략함

	fetch(url, {
	  method: 'POST',
	body: formData
	});

0개의 댓글