html javascript 대용량 파일 업로드 구현 > 영카트5 팁자료실

영카트5 팁자료실

html javascript 대용량 파일 업로드 구현 정보

html javascript 대용량 파일 업로드 구현

본문

분할방식의 업로드 샘플코드입니다.

서버의 업로드 1회 업로드 용량 제한에도 대응하는 코드로,

디테일을 구현하면 이어 올리기 등 또한 구현 가능합니다.

필요하신분들 참고하세요.

눈으로만 검수한 코드라 디버깅이 필요할 수 있습니다.

php


<?php
 
// 파일 업로드 처리
if (isset($_FILES['file'])) {
    $file = $_FILES['file'];
 
    // 파일 크기
    $fileSize = $file['size'];
 
    // 분할 크기 (예: 10MB)
    $chunkSize = 10 * 1024 * 1024;
 
    // 분할된 청크 수
    $numChunks = ceil($fileSize / $chunkSize);
 
    // 임시 디렉토리 생성
    $tempDir = sys_get_temp_dir() . '/file-upload';
    if (!file_exists($tempDir)) {
        mkdir($tempDir, 0777, true);
    }
 
    // 파일 분할
    for ($i = 0; $i < $numChunks; $i++) {
        // 분할된 청크 시작 바이트
        $startByte = $i * $chunkSize;
 
        // 분할된 청크 끝 바이트
        $endByte = min($fileSize, $startByte + $chunkSize - 1);
 
        // 분할된 청크 읽기
        $chunk = fopen($file['tmp_name'], 'rb');
        fseek($chunk, $startByte);
        $chunkData = fread($chunk, $chunkSize);
        fclose($chunk);
 
        // 분할된 청크 저장
        $chunkFile = fopen($tempDir . '/chunk-' . $i, 'wb');
        fwrite($chunkFile, $chunkData);
        fclose($chunkFile);
    }
 
    // 분할된 청크 정보 저장
    $chunkInfo = array();
    for ($i = 0; $i < $numChunks; $i++) {
        $chunkInfo[] = array(
            'name' => 'chunk-' . $i,
            'size' => filesize($tempDir . '/chunk-' . $i)
        );
    }
 
    // 분할된 청크 정보 JSON으로 출력
    echo json_encode($chunkInfo);
}
 

 

html & javascript


<script>
 
const form = document.getElementById('file-upload-form');
const progressBar = document.getElementById('progress-bar');
 
// 파일 선택 이벤트
form.addEventListener('change', (event) => {
    // 업로드할 파일 가져오기
    const file = event.target.files[0];
 
    // 파일 크기
    const fileSize = file.size;
 
    // 분할 크기 (예: 10MB)
    const chunkSize = 10 * 1024 * 1024;
 
    // 분할된 청크 수
    const numChunks = Math.ceil(fileSize / chunkSize);
 
    // 임시 디렉토리 생성
    const tempDir = sys_get_temp_dir() + '/file-upload';
    if (!file_exists(tempDir)) {
        mkdir(tempDir, 0777, true);
    }
 
    // 파일 분할
    for (let i = 0; i < numChunks; i++) {
        // 분할된 청크 시작 바이트
        const startByte = i * chunkSize;
 
        // 분할된 청크 끝 바이트
        const endByte = Math.min(fileSize, startByte + chunkSize - 1);
 
        // 분할된 청크 읽기
        const chunk = file.slice(startByte, endByte + 1);
 
        // 분할된 청크 저장
        const chunkFile = new File([chunk], 'chunk-' + i, {
            type: file.type
        });
 
        // 분할된 청크 업로드
        uploadFile(chunkFile);
    }
});
 
// 파일 업로드 함수
function uploadFile(file) {
    // FormData 객체 생성
    const formData = new FormData();
 
    // 파일 추가
    formData.append('file', file);
 
    // AJAX 요청 생성
    const xhr = new XMLHttpRequest();
 
    // 업로드 진행 이벤트
    xhr.upload.addEventListener('progress', (event) => {
        // 업로드 진행률 계산
        const progress = (event.loaded / event.total) * 100;
 
        // 진행률 표시줄 업데이트
        progressBar.style.width = `${progress}%`;
    });
 
    // 서버 응답 이벤트
    xhr.addEventListener('load', (event) => {
        // 업로드 상태 가져오기
        const status = JSON.parse(event.target.response);
 
        // 업로드 상태 표시
        console.log(`파일: ${status.name}, 크기: ${status.size}, 상태: ${status.status}`);
    });
 
    // 요청 보내기
    xhr.open('POST', 'upload.php');
    xhr.send(formData);
}
 
</script>
 
<form id="file-upload-form"></form>
    <input type="file">
    <button type="submit">업로드</button>
</form>
 
<div id="progress-bar"></div>
추천
5

댓글 2개

전체 401
영카트5 팁자료실 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT