Post

File을 이용해보자!

📌시작하며

이번 프로젝트에서 새롭게 사용한 API가 있다! 바로 File API인데, 여러 자료를 참고해서 구현은 했지만 아직 완전히 이해하고 내 것으로 만든 것은 아니라 제로부터 스스로 작성하긴 어려울 것 같다고 생각했다.🤔 그래서 이번에 File API에 대해 알아보고 프로젝트를 복기해보려고 한다.

✅File API

File API는 웹 애플리케이션이 사용자 로컬 시스템의 파일과 그 콘텐츠에 접근할 수 있도록 하는 API다. 사용자가 자신의 컴퓨터에 있는 이미지를 업로드 해 브라우저에서 표시하고 다시 다운로드 할 수 있다는 것을 생각해보자!

✅Input

먼저 파일을 업로드하기 위해서는, input 태그를 이용해 파일 업로드를 만들 수 있다!

1
<input type="file" id="file" />

그 다음, 시험 삼아 업로드한 파일을 console에서 읽어보자.

1
2
3
4
5
const checkFile = (e) => {
  console.log(e.target.files)
}
const uploadFile = document.getElementById("file")
uploadFile.addEventListener("change", checkFile)

그러면 다음과 같이 FileList 객체 안에 File 객체가 포함되어있는 형태의 데이터를 확인할 수 있다.

FileList는 배열이 아님에 주의한다.

1
2
3
4
5
6
7
8
9
10
11
12
FileList {
  0: File {
    lastModified: 1715825882002,
    lastModifiedDate: Thu May 16 2024 11:18:02 GMT+0900 (한국 표준시),
    name: "연습.pdf",
    size: 1089570,
    type: "application/pdf",
    webkitRelativePath: ""
  },
  length: 1
}

➡️ 형식과 사이즈 제한하기

위에서 확인할 수 있는 값들을 이용해, 사용자가 업로드하는 파일 유형이나 size를 제한할 수 있다.

위의 예제에서 나타난 사이즈 “size: 1089570” 의 경우 해당 파일이 1,089,570 바이트 즉, 약 1.09MB 를 의미한다.

1 메가바이트 (MB) = 1,048,576 바이트 (1,024 * 1,024)

➡️ input 초기화

만약 사용자가 업로드한 이미지를 삭제(초기화) 하고 싶다면, 간단하게 input의 value="" 와 같이 초기화 해주면 된다.

✅ FileReader

FileReader는 JavaScript에서 파일을 비동기적으로 읽을 수 있는 객체다. 주로 파일 업로드, 프리뷰표시, 데이터 처리 등에 이용한다!

사용 할 때는 다음과 같이 인스턴스를 만들어 사용한다.

1
var reader = new FileReader()

그 다음 이 파일을 읽으려면 다음과 같은 메소드를 사용할 수 있다.

➡️ 파일 읽는 법 지정하기

Blob: Binary Large Object의 줄임말로, 웹 애플리케이션에서 바이너리 데이터(컴퓨터에서 사용되는 데이터를 이진 형식으로 나타낸 것)를 나타내는 객체를 말한다.

FileReader.abort(): 읽기 요청을 중단시킨다. 호출 후에는 FileReader 객체의 상태가 “DONE”이된다.

FileReader.readAsArrayBuffer(): 지정된 Blob의 내용을 읽고, 완료되면 결과에 파일 데이터를 나타내는 ArrayBuffer가 포함된다.

FileReader.readAsBinaryString(): 지정된 Blob의 내용을 읽고, 완료되면 읽기가 완료되면, 결과에 파일의 이진 데이터가 문자열 형태로 포함된다.

FileReader.readAsDataURL(): 지정된 Blob의 내용을 읽고, 완료되면 결과에 파일 데이터를 나타내는 data: URL이 포함된다.

FileReader.readAsText(): 지정된 Blob의 내용을 읽고, 완료되면 파일 내용을 나타내는 텍스트 문자열이 포함된다.

➡️ 이미지 프리뷰 예제

FileReader.readAsDataURL() 를 이용해 이미지를 업로드 할 때 프리뷰를 보여줄 수 있다!

예제의 흐름은 다음과 같다.

graph LR; A(input에 이미지 업로드) --> B(FileReader 인스턴스 생성
readAsDataURL메서드 사용해서 file 읽기); B --> C(생성된 url img 태그 src로 이용);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>File 프리뷰 예제</title>
  </head>
  <body>
    <input type="file" id="file" />
    <div id="image">
      <!-- 이미지 태그가 생성 될 자리 -->
    </div>

    <script>
      const container = document.getElementById("image")

      const checkFile = (e) => {
        const readerDataURL = new FileReader() // FileReader 인스턴스 생성

        // FileReader 인스턴스를 사용해 첫 번째 파일을 읽는다.
        readerDataURL.readAsDataURL(e.target.files[0])

        // 데이터 URL 파일을 읽어들일 때 호출 된다.
        readerDataURL.onload = function (event) {
          //url은 result에 저장되어 있다.
          console.log("데이터 URL:", event.target.result)

          //img 태그를 만들어 프리뷰를 생성한다.
          const image = document.createElement("img")
          image.setAttribute("src", event.target.result)
          container.appendChild(image) // 이미지를 새로운 이미지로 교체
        }
      }

      //input의 값이 변경 될 때마다 실행된다.
      const uploadFile = document.getElementById("file")
      uploadFile.addEventListener("change", checkFile)
    </script>
  </body>
</html>

주의해야 할 점은, FileReader()는 비동기로 작동하기 때문에, readerDataURL.onload 를 사용해 로드 된 이후 result에 접근해야 한 다는 것이다!

🗂️참고 사이트

This post is licensed under CC BY 4.0 by the author.