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() 를 이용해 이미지를 업로드 할 때 프리뷰를 보여줄 수 있다!
예제의 흐름은 다음과 같다.
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에 접근해야 한 다는 것이다!