HTML 폼 내 이미지 업로드 및 실시간 미리보기 구현 방법

웹 애플리케이션 개발 시 HTML 폼(Form) 내부에서 이미지 파일을 선택하고, 이를 서버에 전송하기 전 사용자에게 미리보기를 제공해야 할 경우가 많습니다. 기본적으로 HTML 표준에서는 폼 내부에 또 다른 폼을 중첩하는 것을 허용하지 않으므로, 하나의 폼 안에서 파일 선택과 데이터 입력을 동시에 처리하는 효율적인 구조가 필요합니다.

이미지 업로드와 미리보기를 구현하는 가장 권장되는 방식은 JavaScript의 File API를 사용하여 클라이언트 측에서 즉시 미리보기를 생성하고, 사용자가 전체 폼을 제출할 때 파일을 서버로 전송하는 방식입니다. 이 방식은 불필요한 서버 통신을 줄여 사용자 경험을 향상시킵니다.

1. 클라이언트 측 구현 (HTML 및 JavaScript)

아래 코드는 선택된 이미지 파일의 로컬 URL을 생성하여 <img> 태그로 화면에 출력하는 로직입니다. URL.createObjectURL 메서드를 활용하면 서버 업로드 없이도 브라우저 메모리에 저장된 파일 경로를 참조할 수 있습니다.

<!-- HTML 구조 -->
<form id="uploadForm" method="post" action="upload_handler.php" enctype="multipart/form-data">
    <div id="previewContainer" style="margin-bottom: 10px;">
        <!-- 이미지가 여기에 표시됩니다 -->
    </div>
    
    <label for="fileInput" style="display: inline-block; padding: 6px 12px; background-color: #007bff; color: white; cursor: pointer; border-radius: 4px;">
        이미지 선택
    </label>
    <input type="file" id="fileInput" name="user_image" style="display: none;" onchange="renderPreview(this)">
    
    <input type="submit" value="저장하기" style="padding: 6px 12px; cursor: pointer;">
</form>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
    function renderPreview(input) {
        if (input.files && input.files[0]) {
            const readerUrl = window.URL || window.webkitURL;
            const blobUrl = readerUrl.createObjectURL(input.files[0]);
            
            const imageTemplate = `<img src="${blobUrl}" alt="미리보기" style="max-width: 150px; border: 1px solid #ddd; padding: 5px;">`;
            
            $('#previewContainer').html(imageTemplate);
        }
    }
</script>

2. 서버 측 구현 (PHP)

폼이 제출되면 서버에서는 전달된 파일을 검증하고 지정된 디렉토리로 저장해야 합니다. 파일 확장자 체크 및 HTTP POST 방식 업로드 여부를 확인하는 보안 절차가 포함된 로직입니다.

<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['user_image'])) {
    $fileData = $_FILES['user_image'];
    $targetDirectory = "uploads/";
    
    // 파일 정보 추출
    $fileName = basename($fileData['name']);
    $fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
    
    // 허용할 확장자 정의
    $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
    
    // 유효성 검사
    if (!in_array($fileExtension, $allowedExtensions)) {
        die("허용되지 않는 파일 형식입니다.");
    }
    
    if (!is_uploaded_file($fileData['tmp_name'])) {
        die("정상적인 업로드 요청이 아닙니다.");
    }
    
    // 저장 경로 설정 및 파일 이동
    $destination = $targetDirectory . uniqid() . "_" . $fileName;
    
    if (move_uploaded_file($fileData['tmp_name'], $destination)) {
        echo "파일 업로드 성공: " . $destination;
    } else {
        echo "파일 저장 중 오류가 발생했습니다.";
    }
}
?>

이와 같은 방식을 사용하면 사용자는 이미지를 선택하자마자 결과를 확인할 수 있으며, 최종적으로 '저장하기' 버튼을 눌렀을 때만 데이터가 서버로 전송되어 효율적인 리소스 관리가 가능해집니다.

태그: html5 JavaScript PHP FileAPI ImagePreview

9월 5일 16:11에 게시됨