ETC -

axios, XMLHttpRequest 파일 업로드하기

  • -

⚡️axios, XMLHttpRequest 파일 업로드하기

안녕하세요 TriplxLab 입니다.
오늘 파일 업로드하면서 클라이언트에서 처리해야 하는 progressBar에 관해서 살펴보도록 하겠습니다.

<style>
    .progress {height: 10px;}
    .progressContainer{position:relative;width: 450px;padding:20px 10px;margin-top: 15px;height:10px;}
    .progress{position:absolute;width: calc(100% - 20px);height: 10px;}
    .progressTotal{background: rgba(80,90,100,0.15);border-radius: 10px;}
    .progressNow{width: calc(0% - 20px);background: #057FEB;border-radius: 10px;}
    .progressPer{background: transparent; text-align:center;color:#A6A6A6;}
    .progressText{position: absolute; right: 0; top: 50%; transform: translate(100%, -50%)}
</style>
<form id="fileForm" action="/upload-file" method="post" enctype="multipart/form-data">
    <input type="file" name="file" multiple>
    <button type="button" id="btn">전송</button>
</form>

<div class="progressContainer">
    <div class="progress progressTotal"></div>
    <div class="progress progressNow" id="progressNow"></div>
    <div class="progressText">0%</div>
</div>

👉XMLHttpRequest 기반으로 작업한 파일 업로드 기능

XMLHttpRequest 기반으로 작업한 파일 업로드 progressBar를 구현해봤습니다.

<script>
    (() => {
        const $ = (select) => document.querySelector(select)

        const progressBar = (per) => {
            $(".progressText").innerText = Math.floor(per)+" %";
            $(".progressNow").style.width = "calc(" + per + "% - 20px)";
        };

		const xhrFun = (e) => {
			e.preventDefault();
            const xhr = new XMLHttpRequest();

            xhr.upload.addEventListener('loadstart', function(e) {
                console.log('시작')
            });
            /*
                progress 이벤트 핸들러는
                전송할 총 바이트 수 total과 이벤트 및 loaded 필드에서 지금까지 전송 된 바이트 수를 받습니다.
            */
            xhr.upload.addEventListener('progress', function(e) {
                if( e.lengthComputable ) {
                    // 업로드 진행률 계산
                    const percentComplete = Math.floor((e.loaded / e.total) * 100); 
                    console.log(percentComplete)
                    progressBar(percentComplete)
                } else {
                    // 측정 불가
                }
            });
            xhr.upload.addEventListener('load', function(e) {
                console.log('upload complete', e);
            });
            xhr.upload.addEventListener('loadend', function(e) {
                console.log('완료')
            });

            xhr.upload.addEventListener('error', function(e) {
                console.log('요청이 실패했을 때')
            });
            xhr.upload.addEventListener('abort', function(e) {
                console.log('요청이 중단되었을 때')
            });
            xhr.upload.addEventListener('timeout', function(e) {
                console.log('요청이 완료되기 전에 작성자가 지정한 타임아웃이 지났을 때')
            });

            xhr.open('POST', '/upload-file', true);
            // xhr.open('POST', '/upload-file', false);  //false로 하면 동기 처리

            const files = $('[name=file]').files;
            const formData = new FormData();
            formData.append('avatar', files[0]);

            xhr.send(formData);
        };

        $('#btn').addEventListener('click', xhrFun);
    })();
</script>

👉axios 기반으로 작업한 파일 업로드 기능

axios 기반으로 작업한 파일 업로드 progressBar를 구현해봤습니다.

<script>
    (() => {
        const $ = (select) => document.querySelector(select)

        const progressBar = (per) => {
            $(".progressText").innerText = Math.floor(per)+" %";
            $(".progressNow").style.width = "calc(" + per + "% - 20px)";
        };

        const upload = async (e) => {
            e.preventDefault();
            const config = {
                onUploadProgress: function(e) {
                    if(e.lengthComputable){
                        // 업로드 진행률 계산
                        const percentCompleted = Math.round((e.loaded / e.total) * 100)
                        console.log(percentCompleted)
                        progressBar(percentCompleted)
                    } else {
                        // 측정 불가
                    }
                }
            }

            const files = $('input[type="file"]').files
            let data = new FormData()
            data.append('file', files[0])

            await axios.post('/avatar', data, config)
                .then(res => console.log(res))
                .catch(err => console.log(err))
        };

        $('#btn').addEventListener('click', upload);
    })()
</script>

axios를 사용하게 되면 지원하는 메소드가 별루 없어서 디테일하게 작업해야 하는 상황에서는 못쓸것 같다.
공식 API 문서를 봤는데 '파일 업로드에 대한 진행 이벤트 처리를 허용합니다.'라는 onUploadProgress 메소드 말고는 딱히 다른 메소드는 찾을수가 없었다.(아니면 내가 원하는 시점을 따로 메소드를 만드는 방법도 있다.😭😭)

반면 XMLHttpRequest는 다양한 시점의 메소드를 지원해주고 있어서 디테일하게 작업해야 하는 상황이 생기면 유용하게 사용할수
있을것 같다.

🎯소스코드 파일 공유

전체 소스코드를 github에도 공유합니다.😃🔥👍

 

GitHub - younhoso/younhoso

Contribute to younhoso/younhoso development by creating an account on GitHub.

github.com

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.