Summary

  • W3C는 2009년 11월 17일 File API의 첫 공개 작업 초안을 냈다. 이 문서는 사용자가 고른 파일의 FileList와 이벤트를 통해 읽기 과정을 알리는 FileReader를 설명했다.
  • 2013년 Last Call 초안과 2015년 작업 초안은 Blob, 비동기 읽기, blob URL을 다듬었다. 페이지에서 파일을 확인하는 일과 서버로 보내는 일은 서로 다른 단계였다.

사진관에 인화할 사진 한 장을 가져간다. 직원은 그 사진을 살펴보고 크기를 묻는다. 그런데 갑자기 손님의 집으로 가서 모든 서랍을 뒤지겠다고 한다면, 인화 주문은 그 자리에서 끝날 것이다. 웹에서도 같은 구분이 필요했다. 페이지가 사진의 내용을 다루려면 선택된 파일을 받을 방법이 있어야 하지만, 그것이 컴퓨터의 다른 폴더를 찾아다닐 이유가 되지는 않는다.

2009년 11월 17일 W3C의 첫 공개 File API 작업 초안은 개별적으로 선택된 파일에서 출발했다. <input type="file">이 선택 창을 열 수 있고, FileList가 그 결과를 담는다. File에는 이름과 종류 같은 정보가 있으며, Blob은 원시 바이트와 그 일부를 나타낸다. FileReader는 내용을 읽고 진행 상황을 이벤트로 알린다. 브라우저가 페이지에 넘긴 것은 사람이 고른 물건 하나를 설명하는 객체였다.

파일 업로드 양식 자체는 이미 있었다. 새로워진 것은 보내기 전에 페이지가 파일을 만져 볼 수 있게 된 점이다. 2009년 초안은 readAsBinaryString, readAsText, readAsDataURL을 비동기 읽기 방법으로 적었다. 선택한 사진을 미리 보여 주고, 텍스트를 열어 보며, 잘못 고른 파일이라면 전송 전에 바꿀 수 있다. 이전에는 서버에 보내고 나서야 눈치챘을 실수를 브라우저 화면에서 발견할 수 있었다.

초안의사용 사례는 사진보다 범위가 넓다. 노래 가사 보기 앱은 사용자가 선택한 재생목록 파일을 읽고 곡을 정리할 수 있다. 달력 앱은 로컬 일정 파일을 읽어 다른 일정과 합친 다음 동기화를 제안할 수 있다. 파일은 서버에 배달할 소포만이 아니다. 웹페이지 안에서 읽고 분류하고 확인할 작업 재료가 된다.

그래서 선택의 순간이 중요했다. 2009년 초안의 보안 논의는 FileReader가 읽는 파일을 사용자가 먼저 골랐다고 전제했다. 선택 창을 계속 띄워 억지로 파일을 고르게 하는 경우, 시스템의 민감한 파일, 선택 뒤 디스크에서 바뀌는 파일도 짚었다. 로컬 파일은 페이지에 적힌 고정 문장이 아니다. 다른 프로그램이 고칠 수 있고, 브라우저가 읽기를 거절해야 할 수도 있다. 사진관 카운터에 놓인 사진도 손님 손에서 떨어진 뒤의 모든 순간이 똑같지는 않다.

2013년 9월 12일 Last Call 작업 초안에서는 부품마다 맡은 일이 더 또렷해졌다. FileList는 선택된 객체를 담고, 바꿀 수 없는 원시 데이터를 뜻하는 Blob은 일부를 잘라 쓸 수 있다. File은 이름과 수정 시각 등을 더한다. FileReader는 비동기로 읽으면서 진행, 완료, 오류 이벤트를 보낸다. 초안의 예시는 선택한 파일을 텍스트로 읽으며 진행 막대를 갱신한다. 큰 파일이나 느린 저장장치를 만나도 페이지는 묵묵히 얼어붙는 대신 지금 무슨 일이 벌어지는지 알려 줄 수 있다.

또 하나의 문제는 웹의 URL 습관이었다. 페이지의 이미지 요소는 주소를 원하지만, 사용자가 고른 사진은 로컬 객체다. blob URL이 둘을 잇는다. 2015년 4월 21일 작업 초안은 URL.createObjectURL()로 참조를 만들어 사진을 보여 주고, 사용이 끝나면 URL.revokeObjectURL()로 거두는 예를 제시했다. 오래 남겨 둔 참조가 문제를 만들 수 있다는 설명도 있다. 미리보기 표를 받아 들었으면 사진을 찾은 뒤 표를 치워야 한다.

2015년 문서의 작은 규칙 하나는 이 설계의 성격을 잘 보여 준다. File.name은 파일 이름을 주되 상위 폴더의 경로는 주지 않는다. 페이지가 미리보기 옆에 사진 이름을 적는 데 내 폴더 구조가 필요할 리 없다. 초안은 blob URL도 만든 페이지의 출처에 묶고 다른 출처에서 온 요청은 실패하도록 설명했다. 객체 하나를 쓸 수 있게 만드는 데 서류함의 배치도까지 건넬 필요는 없었다.

W3C의 공식 발표 기록에는 2009년 첫 공개 작업 초안, 2013년 Last Call, 2015년 또 다른 작업 초안이 차례로 남아 있다. 이 과정은 하루아침에 모든 웹사이트가 파일을 안전하게 다루게 되었다는 이야기가 아니다. 사람이 고른 대상을 브라우저와 페이지가 같은 방식으로 이해하도록 여러 해에 걸쳐 규칙을 다듬은 이야기다.

읽기가 끝나면 결정권은 애플리케이션으로 넘어간다. 페이지 안에서 사진을 손질할 수도 있고, 다른 웹 기능으로 서버에 바이트를 보낼 수도 있다. 화면에 미리보기가 떴다는 사실만으로 업로드가 끝난 것은 아니다. 파일을 골랐다는 사실만으로 이후 복사본의 목적지가 설명되는 것도 아니다. File API가 첫 전달을 정확하게 만들었기에 다음 행동을 따로 물을 수 있게 되었다.

잘못 고른 사진은 전송 전에 바꿀 수 있다. 달력 파일은 동기화 전에 살펴볼 수 있다. 큰 문서는 읽기 진행 상태를 보여 줄 수 있다. 화려한 폭죽은 없어도, 매일 반복되는 파일 전달이 덜 서툴어졌다. 직원은 카운터에 놓인 사진을 제대로 다루게 되었고, 나머지 서랍은 주인 곁에 남았다.