이전 파이널 프로젝트를 TypeScript로 리팩토링하는 과정에서 File API와 File Reader API에 관해 찾아 본것이 있어 기록을 남겨본다.
파일 API는 주로 input태그에서 주로 사용된다. type이 file인 input태크를 JavaScript로 선택한 후 onchange 이벤트 핸들러를 붙여 파일을 선택할 때마다 함수가 호출되게 해줄 수 있다.
<input type="file" id="photoFile" multiple/>
let file = document.getElementById("photoFile")
file.onchange = function(e) {
let files = e.target.files; // FileList 객체
console.log(files); // { 0: File, 1: File, length: 2 }
위의 예시는 두 개의 사진을 올렸을 때 발생하는 이벤트이다. e.target
은 이벤트가 일어난 대상, 즉 input 자신을 가리키고, 그 아래 files에 어떤 파일들을 올렸는지 나오게 된다.
첫 번재에 있는 파일을 console.log(files[0])
으로 찍어보게 되면 아래와 같이 파일에 대한 정보들이 들어가 있는것을 확인할 수 있다.
{
name: 'zerocho.png', // 파일 이름
size: 74120, // byte 단위 파일 크기
lastModified: 1495791249810, // 올린 시간 timestamp
type: 'image/png'
}
헌데 여기서 정작 중요한 파일 데이터 자체를 찾아볼 수가 없다. 파일은 숨어져 있는데, 숨어져 있는 데이터를 읽으려면 FileReader API를 사용해야 한다.
window.File.Reader
에 위치하고, new FileReader()
로 파일리더를 만들어 준 후 사용할 수 있다.
파일을 읽는 방법으로는 readAsText, readAsDataURL, readAsArrayBuffer, readAsBinaryString 4가지의 방법이 있다. 참고로 FileReader가 즉시 파일을 읽는게 아니기 때문에 onload 이벤트 핸들러를 붙여서 콜백 파일을 다 읽었다는 것을 알려주도록 해야한다.
file.onchange = function(e) {
let fileReader = new FileReader();
fileReader.readAsText(e.target.files[0]);
fileReader.onload = function(e) {
console.log(e.target.result);
}
}
// 결과
데이터 URL로 만드는 방법이다.
file.onchange = function(e) {
let fileReader = new FileReader();
fileReader.readAsDataURL(e.target.files[0]);
fileReader.onload = function(e) {
console.log(e.target.result);
}
}
// 결과
처음에 나와있는 base64는 base64로 인코딩했다는 뜻이다. base64로 인코딩한 경우 브라우저가 이 문자열을 인식해서 원래 데이터로 만들어주게 된다. 길이가 길긴해도 이 문자열을 주소창에 치면 브라우저가 이 파일을 표시한다. 즉, 파일 정보를 주소처럼 활용할 수 있게 되는 것이다. <img>
태그의 src
로도 사용할 수 있다.
ArrayBuffer라는 객체를 반환한다. 데이터를 일정한 크기로 조금씩 조금씩 서버로 보낼 수 있다.
file.onchange = function(e) {
let fileReader = new FileReader();
fileReader.readAsArrayBuffer(e.target.files[0]);
fileReader.onload = function(e) {
console.log(e.target.result); // ArrayBuffer 객체
}
}
이진데이터를 반환한다.
file.onchange = function(e) {
let fileReader = new FileReader();
fileReader.readAsBinaryString(e.target.files[0]);
fileReader.onload = function(e) {
console.log(e.target.result);
}
}
// 결과
reference
Zerocho
html5 file API