JavaScript

[JavaScript] 첨부파일 다중파일 multiple 업로드

purecho 2021. 9. 2. 11:20

 

 

Ver1. 파일 첨부 시 최대 개수가 넘으면 현재 선택된 파일은 전부 첨부를 안 하는 방식.

See the Pen [T] 다중파일 업로드 v1 by green526 (@green526) on CodePen.

 

 

 

 

Ver2. 파일 첨부 시 최대 개수를 넘으면 최대 개수 까지만 첨부하는 방식.

See the Pen by green526 (@green526) on CodePen.

 

 

 

 

 

코드
더보기

html

<div class="insert">
    <form method="POST" onsubmit="return false;" enctype="multipart/form-data">
        <input type="file" onchange="addFile(this);" multiple />
        <div class="file-list"></div>
    </form>
</div>

 

css

.insert {
    padding: 20px 30px;
    display: block;
    width: 600px;
    margin: 5vh auto;
    height: 90vh;
    border: 1px solid #dbdbdb;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
.insert .file-list {
    height: 200px;
    overflow: auto;
    border: 1px solid #989898;
    padding: 10px;
}
.insert .file-list .filebox p {
    font-size: 14px;
    margin-top: 10px;
    display: inline-block;
}
.insert .file-list .filebox .delete i{
    color: #ff5353;
    margin-left: 5px;
}

 

javascript

var fileNo = 0;
var filesArr = new Array();

// Ver1.
/* 첨부파일 추가 */
function addFile(obj){
    var maxFileCnt = 5;   // 첨부파일 최대 개수
    var attFileCnt = document.querySelectorAll('.filebox').length;    // 기존 추가된 첨부파일 개수
    var remainFileCnt = maxFileCnt - attFileCnt;    // 추가로 첨부가능한 개수
    var curFileCnt = obj.files.length;  // 현재 선택된 첨부파일 개수

    // 첨부파일 개수 확인
    if (curFileCnt > remainFileCnt) {
        alert("첨부파일은 최대 " + maxFileCnt + "개 까지 첨부 가능합니다.");
    } else {
        for (const file of obj.files) {
            // 첨부파일 검증
            if (validation(file)) {
                // 파일 배열에 담기
                var reader = new FileReader();
                reader.onload = function () {
                    filesArr.push(file);
                };
                reader.readAsDataURL(file);

                // 목록 추가
                let htmlData = '';
                htmlData += '<div id="file' + fileNo + '" class="filebox">';
                htmlData += '   <p class="name">' + file.name + '</p>';
                htmlData += '   <a class="delete" onclick="deleteFile(' + fileNo + ');"><i class="far fa-minus-square"></i></a>';
                htmlData += '</div>';
                $('.file-list').append(htmlData);
                fileNo++;
            } else {
                continue;
            }
        }
    }
    // 초기화
    document.querySelector("input[type=file]").value = "";
}


// Ver2.
/* 첨부파일 추가 */
function addFile(obj){
    var maxFileCnt = 5;   // 첨부파일 최대 개수
    var attFileCnt = document.querySelectorAll('.filebox').length;    // 기존 추가된 첨부파일 개수
    var remainFileCnt = maxFileCnt - attFileCnt;    // 추가로 첨부가능한 개수
    var curFileCnt = obj.files.length;  // 현재 선택된 첨부파일 개수

    // 첨부파일 개수 확인
    if (curFileCnt > remainFileCnt) {
        alert("첨부파일은 최대 " + maxFileCnt + "개 까지 첨부 가능합니다.");
    }

    for (var i = 0; i < Math.min(curFileCnt, remainFileCnt); i++) {

        const file = obj.files[i];

        // 첨부파일 검증
        if (validation(file)) {
            // 파일 배열에 담기
            var reader = new FileReader();
            reader.onload = function () {
                filesArr.push(file);
            };
            reader.readAsDataURL(file)

            // 목록 추가
            let htmlData = '';
            htmlData += '<div id="file' + fileNo + '" class="filebox">';
            htmlData += '   <p class="name">' + file.name + '</p>';
            htmlData += '   <a class="delete" onclick="deleteFile(' + fileNo + ');"><i class="far fa-minus-square"></i></a>';
            htmlData += '</div>';
            $('.file-list').append(htmlData);
            fileNo++;
        } else {
            continue;
        }
    }
    // 초기화
    document.querySelector("input[type=file]").value = "";
}



/* 첨부파일 검증 */
function validation(obj){
    const fileTypes = ['application/pdf', 'image/gif', 'image/jpeg', 'image/png', 'image/bmp', 'image/tif', 'application/haansofthwp', 'application/x-hwp'];
    if (obj.name.length > 100) {
        alert("파일명이 100자 이상인 파일은 제외되었습니다.");
        return false;
    } else if (obj.size > (100 * 1024 * 1024)) {
        alert("최대 파일 용량인 100MB를 초과한 파일은 제외되었습니다.");
        return false;
    } else if (obj.name.lastIndexOf('.') == -1) {
        alert("확장자가 없는 파일은 제외되었습니다.");
        return false;
    } else if (!fileTypes.includes(obj.type)) {
        alert("첨부가 불가능한 파일은 제외되었습니다.");
        return false;
    } else {
        return true;
    }
}

/* 첨부파일 삭제 */
function deleteFile(num) {
    document.querySelector("#file" + num).remove();
    filesArr[num].is_delete = true;
}

/* 폼 전송 */
function submitForm() {
    // 폼데이터 담기
    var form = document.querySelector("form");
    var formData = new FormData(form);
    for (var i = 0; i < filesArr.length; i++) {
        // 삭제되지 않은 파일만 폼데이터에 담기
        if (!filesArr[i].is_delete) {
            formData.append("attach_file", filesArr[i]);
        }
    }

    $.ajax({
        method: 'POST',
        url: '/register',
        dataType: 'json',
        data: formData,
        async: true,
        timeout: 30000,
        cache: false,
        headers: {'cache-control': 'no-cache', 'pragma': 'no-cache'},
        success: function () {
            alert("파일업로드 성공");
        },
        error: function (xhr, desc, err) {
            alert('에러가 발생 하였습니다.');
            return;
        }
    })
}

 

 

 

 

참고
더보기

https://velog.io/@xedni/JavaScript-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C-FormData

 

JavaScript | 파일 업로드 (FormData)

업로드 된 파일을 자바스크립트로 다루는 방법에 대해 알아보자.

velog.io

 

https://taeny.dev/javascript/file-object/

 

💾 자바스크립트 File 객체

자바스크립트에서 이미지나 동영상, 오디오 등 대용량 파일을 업로드할 때, file 객체를 이용한다. 이번 포스팅에서는 file 객체에 대한 내용을 정리해보았다. 1. File 객체 2. URL로 접근 3. FileReader로

taeny.dev

 

https://developer.mozilla.org/ko/docs/Web/HTML/Element/Input/file

 

- HTML: Hypertext Markup Language | MDN

file 유형의

요소에는 저장 장치의 파일을 하나 혹은 여러 개 선택할 수 있습니다. 그 후, 양식을 제출해 서버로 전송하거나, File API를 사용한 JavaScript 코드로 조작할 수 있습니다.

developer.mozilla.org

 

https://hianna.tistory.com/346

 

[HTML] input type='file' 속성 알아보기 ( 파일 입력 )

웹페이지에서 사용자의 로컬 파일을 입력받기 위해서는 다음과 같이 input 태그의 type속성을 file로 지정하는 방법을 사용합니다. See the Pen read file by anna (@hianna) on CodePen. 여기에서는 input의 type..

hianna.tistory.com

 

https://tyrannocoding.tistory.com/54

 

파일 업로드 쉽게 구현하기 (Spring Ajax 다중파일 업로드 & 개별삭제 & 개수제한 & 초기화) ②

파일 업로드 게시판 파일 업로드가 되는 게시판은 대부분의 사이트에 꼭 하나씩 있습니다. 사이트를 구축할 때 기본이 되는 파일 업로드이지만 불편함 없이 다양한 기능이 필요할 때도 있습니

tyrannocoding.tistory.com