파일 업로드 진행률 표시하기|SweetAlert2와 Fetch로 실시간 UX 구현

대용량 파일을 업로드할 때 진행률을 시각적으로 표시하면 사용자는 현재 상황을 쉽게 이해하고, 전송 중 오류나 중단 시 혼란을 줄일 수 있습니다. 이번 글에서는 SweetAlert2와 JavaScript Fetch API를 활용해 업로드 진행률을 실시간으로 표시하는 방법을 실무 예제 중심으로 살펴보겠습니다.

파일 업로드 진행률 표시가 필요한 이유

웹에서 파일 업로드가 오래 걸릴 경우, 사용자는 진행 상황을 알 수 없으면 불안감을 느끼고 페이지를 떠나버릴 수 있습니다.
진행률 바(Progress Bar)를 제공하면 시각적인 피드백을 통해 다음과 같은 장점을 얻을 수 있습니다.

  • 업로드 진행 상황을 실시간으로 안내
  • 사용자 만족도 및 신뢰도 상승
  • 업로드 실패 시 원인 파악 용이

💡 RAO TIP
업로드 진행률은 특히 대용량 이미지, 동영상, 백업 파일 등에서 꼭 필요한 기능입니다.
진행률 표시를 통해 사용자가 페이지를 이탈하지 않도록 유도하세요.

기본 HTML 구조

간단한 파일 업로드 폼을 준비합니다.

<form id="uploadForm" enctype="multipart/form-data">
  <input type="file" name="file" required>
  <button type="submit">업로드</button>
</form>
HTML

SweetAlert2 진행률 모달 준비

SweetAlert2에서 진행률 바를 표시하기 위해 커스텀 HTML을 삽입합니다.

function showUploadProgress(progress) {
  Swal.fire({
    title: '업로드 중...',
    html: `
      <div style="width: 100%; background: #eee; border-radius: 8px; overflow: hidden;">
        <div id="progressBar" style="
          width: ${progress}%;
          height: 20px;
          background: #4caf50;
          transition: width 0.3s;
        "></div>
      </div>
      <p style="margin-top: 10px;">${progress}%</p>
    `,
    allowOutsideClick: false,
    showConfirmButton: false
  });
}
JavaScript

설명

  • 진행률 바는 SweetAlert2의 html 옵션으로 커스텀 UI를 삽입합니다.
  • transition을 이용해 부드러운 애니메이션 효과를 추가했습니다.

JavaScript Fetch API와 진행률 연동

업로드 진행률을 표시하기 위해 XMLHttpRequest (XHR)를 사용하는 방식과
Fetch + XMLHttpRequest 혼합 방식이 있습니다.
여기서는 XHR의 progress 이벤트를 활용해 실시간으로 업데이트합니다.

document.getElementById('uploadForm').addEventListener('submit', function(e) {
  e.preventDefault();

  const formData = new FormData(this);
  const xhr = new XMLHttpRequest();

  xhr.open('POST', '/upload.php', true);

  // 진행률 이벤트
  xhr.upload.addEventListener('progress', function(e) {
    if (e.lengthComputable) {
      const percent = Math.round((e.loaded / e.total) * 100);
      showUploadProgress(percent);
    }
  });

  // 업로드 완료 후 처리
  xhr.onload = function() {
    if (xhr.status === 200) {
      Swal.fire('완료!', '파일 업로드가 성공적으로 완료되었습니다.', 'success');
    } else {
      Swal.fire('오류', '업로드 중 문제가 발생했습니다.', 'error');
    }
  };

  xhr.send(formData);
});
JavaScript

💡 RAO TIP

  • progress 이벤트에서 e.loadede.total을 사용해 실시간 비율 계산
  • SweetAlert2 모달을 계속 업데이트하여 동적으로 반영

SweetAlert2 모달 업데이트하기

위 예제에서는 showUploadProgress() 함수가 모달을 계속 새로 띄우기 때문에 깜빡임 현상이 발생할 수 있습니다.
이 문제는 Swal.getHtmlContainer()를 사용해 기존 모달 내용을 업데이트하여 해결합니다.

function updateProgress(percent) {
  const progressBar = Swal.getHtmlContainer().querySelector('#progressBar');
  if (progressBar) {
    progressBar.style.width = percent + '%';
  }

  const percentText = Swal.getHtmlContainer().querySelector('p');
  if (percentText) {
    percentText.textContent = percent + '%';
  }
}
JavaScript

수정된 progress 이벤트:

xhr.upload.addEventListener('progress', function(e) {
  if (e.lengthComputable) {
    const percent = Math.round((e.loaded / e.total) * 100);
    updateProgress(percent);
  }
});
JavaScript

서버 측 PHP 업로드 코드 예시

업로드 처리를 위한 간단한 PHP 예제입니다.

<?php
// upload.php
if ($_FILES['file']['error'] === UPLOAD_ERR_OK) {
    $uploadDir = __DIR__ . '/uploads/';
    if (!is_dir($uploadDir)) {
        mkdir($uploadDir, 0755, true);
    }

    $filePath = $uploadDir . basename($_FILES['file']['name']);
    if (move_uploaded_file($_FILES['file']['tmp_name'], $filePath)) {
        echo json_encode(['status' => 'success', 'message' => '업로드 성공']);
    } else {
        http_response_code(500);
        echo json_encode(['status' => 'error', 'message' => '업로드 실패']);
    }
} else {
    http_response_code(400);
    echo json_encode(['status' => 'error', 'message' => '파일 오류 발생']);
}
?>
PHP

UX 향상을 위한 추가 팁

  1. 최대 업로드 파일 크기 안내
    • 업로드 전 SweetAlert2 모달에서 허용 용량을 미리 안내
    • 예: “최대 20MB까지 업로드 가능합니다.”
  2. 업로드 취소 기능 추가
    • SweetAlert2의 취소 버튼으로 xhr.abort() 처리 가능
  3. 다중 파일 업로드 지원
    • <input type="file" multiple>로 확장 가능

💡 RAO TIP

  • 진행률 표시와 함께 예상 시간, 취소 버튼 등을 추가하면 UX가 한층 향상됩니다.

마무리

이번 글에서는 SweetAlert2 + XHR을 이용해 실시간 파일 업로드 진행률 표시를 구현했습니다.
진행률 바를 통해 사용자에게 명확한 피드백을 제공하면, 긴 업로드 과정에서도 사용자 만족도를 높일 수 있습니다.
다음 글에서는 자동완성 입력 UI를 구현해 폼 UX를 한 단계 더 발전시켜보겠습니다.

Summary in English

Learn how to implement a real-time file upload progress bar using SweetAlert2 and JavaScript. This guide covers creating a progress modal, updating it dynamically, and handling server-side uploads for a smooth user experience.

“이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.”

대표 사진: UnsplashMike van den Bos

위로 스크롤