개발 기록이

[웹개발] 파일기능(1) <input type="file"> 속성과 자바스크립트로 파일 정보 보내기 본문

웹 개발/Front-end

[웹개발] 파일기능(1) <input type="file"> 속성과 자바스크립트로 파일 정보 보내기

studyingbackhoe 2024. 3. 23. 17:33

파일 관련 기능 구현할 때 제대로 정리가 안 되는 것 같아서 프론트단에서부터 서버에서 어떻게 file 값을 받고 처리하는지 정리를 해보려고 한다.
 

1. <input type="file"> 속성

<input type="file"> 은 웹에서 사용자의 로컬 파일을 입력받을 수 있는 기능을 하는데 관련 속성에 대해 알아보자.

1) accept

  • 업로드를 허용하고 싶은 확장자를 지정할 수 있다.
  • 그러나 파일 확장자를 지정해 줄 뿐 실제 내가 지정한 확장자 외에 다른 확장자의 파일을 못 올리게 하는 속성은 아니다. (특정 파일의 확장자만 입력받도록 하려면 별도의 코드 작업이 필요하다.)

1-1) 확장자명을 직접 입력(콤마로 구분)

<input type="file" accept=".jpg, .txt, .png">

 
1-2) MIME 타입 지정

<input type="file" accept="image/gif">

 

2) capture

모바일에서 이미지를 업로드할 때 사용되는 속성전/후면 카메라를 작동시킬 수 있다.

<input type="file" capture="user"> <!-- 전면카메라 -->
<input type="file" capture="environment"> <!-- 후면카메라 -->

3) files

사용자가 파일을 선택하면, 선택된 파일의 목록이 FileList 객체 형태로 files라는 속성에 저장이 된다.

4) multiple

사용자가 파일 선택 창에서 다수의 파일을 선택할 수 있도록 하는 속성

<input type="file" multiple>

5) required

  • 파일을 반드시 선택하고자 할 때 사용하는 속성
  • 미선택 시 form에서 submit을 하면 파일을 선택하라는 메시지가 나온다.
<form>
  <input type="file" required/>
  <input type="submit">
</form>

 

 

2. 자바스크립트로 선택한 파일 정보 확인하기

 
<input type="file">에서 파일을 선택하면, files 속성을 통해 파일에 접근이 가능하다. files 속성은 FileList라는 유사 배열 객체(Array-like object)를 반환하는데 다음과 같이 여러 개의 파일을 업로드한 경우 업로드한 순서대로 각 파일 정보를 가져올 수 있다.

document.getElementById('fileArea').addEventListener('change', function(e) {
  
  let file1 = e.target.files[0]; // FileList 객체의 첫번째 파일값
  let file2 = e.target.files[1]; // FileList 객체의 두번째 파일값
  let file3 = e.target.files[2]; // FileList 객체의 세번째 파일값
  
  ...
});

 

*유사 배열 객체(Array-like object) 란?
- 배열과 유사한 동작을 하는 객체를 의미하며 인덱스로 접근할 수 있고 length 속성을 갖는다. 그러나 일반적인 배열처럼 slice(), map(), filter() 등과 같은 배열의 메서드를 직접 사용할 수는 없다는 특징이 있다. 

 
또한, change 이벤트 발생 없이 직접적으로 document.getElementById('fileArea').files[0]; 처럼은 값을 가져올 수 없다. files 속성은 선택한 파일의 목록을 가져오게 되는데 change 이벤트가 발생하면서 파일을 선택했을 때 해당 정보가 files 속성에 채워지는 방식이기 때문에 change 이벤트 발생 시 files 정보를 가져올 수 있다.

 

files 속성을 통해서는 다음과 같은 파일 정보를 알 수 있다.

See the Pen input accept by eun gu (@eun-gu) on CodePen.

 

3. 파일정보를 서버로 보내기

1) FormData 사용

FormData 객체는 폼 데이터를 동적으로 처리하기 위한 자바스크립트 내장객체인데 일반적으로 파일 업로드를 포함한 다중 데이터를 처리할 때 사용된다. 다음과 같이 FormData 객체에 파일 정보를 담아 AJAX를 통해 서버에 보낼 수 있다.

<form id="formArea">
  <input type="file" id="fileArea">
  <button type="submit">서버로 보내기</button>
</form>
document.getElementById('formArea').addEventListener('submit', function(event) {
    
    var formData = new FormData(); 
    var file = event.target.files[0]; 

    formData.append('file', file); 
    
    // FormData 전송
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/uploadFile', true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            console.log('파일 전송 성공');
        } else {
            console.error('파일 전송 실패');
        }
    };
    xhr.send(formData);
});

 
FormData로 파일 정보를 전송하는 경우, FormData 객체는 HTTP 요청의 일부로 전송되는 데이터를 쉽게 구성하기 위한 특수한 객체이기 때문에 프론트단에서는 FormData를 직접 콘솔로 출력해서 볼 수 없고 전송 여부만 확인이 가능하다.
 

2) <form> 이용하여 submit 하기

form 태그 안에 enctype="multipart/form-data" 속성을 넣어준다.
 

* enctype 속성이란?
- HTML 폼 요소의 속성 중 하나로, 폼 데이터가 서버로 전송될 때 인코딩 방식을 지정해 준다.

 
폼 데이터에 파일 정보를 함께 전송하기 위해서는 enctype의 속성 값을 multipart/form-data로 설정해주어야 한다. 해당 속성을 명시해주지 않으면 기본값으로 application/x-www-form-urlencoded로 설정되어 있는데 이 경우에는 텍스트 데이터를 전송하는 속성값이기 때문에 파일과 같은 바이너리 데이터를 전송할 수 없다. multipart/form-data 은 바이너리 데이터를 포함한 폼 데이터를 전송할 수 있게 해 줄 수 있기 때문에 파일과 같은 값을 서버로 보내기 위해서는 반드시 해당 속성을 명시해줘야 한다.

<form action="/uploadFile" method="POST" enctype="multipart/form-data">
    <input type="file" id="fileArea">
    <button type="submit">서버로 보내기</button>
</form>

 

 

📌 업로드한 파일을 서버단에서 처리하는 방법 확인하기

 

[웹개발] 파일기능(2) MultipartFile와 MultipartHttpServletRequest 로 업로드한 파일 처리하기

지난 포스팅에 이어서 업로드한 파일을 자바 서버단에서 처리하는 방법에 대해 알아보려고 한다. 예전에는 주로 MultipartHttpServletRequest를 사용하여 멀티파트 요청을 처리했지만, Spring 3.1 이후부

studyingbackhoe.tistory.com


출처: OpenAI ChatGPT (https://openai.com), https://developer.mozilla.org/ko/docs/Web/HTML/Element/input/file, https://hianna.tistory.com/346, https://ttowa.tistory.com/entry/HTML-input-typefile-%EC%86%8D%EC%84%B1property-%EC%A0%95%EB%A6%AC