Firefox 4 – FormData 와 새로운 File.url 객체

이 글은 Gecko 내부의 콘텐트 관련 기능에 많은 작업을 하고 있는 조나스 시킹의 객원 글입니다. 그는 우리가 이전에 얘기했던 FormData에 대해서 다루기는 하지만, 거기에 더하여 Firefox 4에 추가된 File API의 중요한 부분인 File.url과 FormData를 어떻게 연계할 수 있는지를 보여줍니다.

Firefox 4는 파일을 보다 쉽고 편하게 다룰 수 있는 기능들을 계속해서 추가하고 있습니다. Firefox 4 베타 1에서는 File.urlFormData라는 두 가지는 기능을 사용할 수 있습니다. 이번 글에서는 이 두 기능에 대해 간략한 소개를 할 것입니다.

Firefox는 3.6부터 FileReader 객체를 사용하여 파일을 읽는 표준적인 방법을 지원합니다. 이 객체를 사용하면 파일의 내용을 메모리로 읽어들여 내용을 분석하거나 사용자에게 보여줄 수 있습니다. 예를 들어 사용자에게 이미지 미리보기를 제공하는 경우 다음과 같은 스크립트를 사용할 수 있습니다.

var reader = new FileReader();
reader.onload = function() {

  previewImage.src = reader.result;
}
reader.readAsDataURL(myFile);

여기에는 주목해야할 두 가지 아쉬운 점이 있습니다. 무엇보다도 reader.result는 파일의 전체 콘텐트를 담고 있는 데이터 URL 입니다. 즉, 파일 전체 내용이 모두 메모리에 저장됩니다. 게다가 데이터 URL은 보통 base64로 인코팅되고 각각의 인코딩된 문자는 보통 메모리의 2바이트를 사용하는 자바스크립트 문자로 저장됩니다. 결국 위의 코드로 10MB의 이미지를 읽으면 reader.result는 26.7MB라는 커다란 문자열이 됩니다.

또 다른 아쉬운 점은 위의 코드는 디스크로부터 파일을 읽기위해 비동기적 이벤트를 사용해야하만 하는데 그로 인해 다소 복잡하다는 것입니다.

Firefox 4 베타 1 에서는 위의 예제 대신에 다음과 같은 코드를 사용할 수 있습니다.

previewImage.src = myFile.url;

이 예제는 File API 명세에 정의돼 있는 File.url 속성을 사용합니다. 이 속성은 약 40자 정도의 짧은 URL을 반환합니다. 이 URL의 내용은 보통 신경쓸 필요가 없습니다. 하지만, 재미로 잠깐 살펴보면 여기에는 특별한 방법에 의해 임의로 생성된 구분자가 앞에 붙어 있습니다.

이러한 URL은 보통 URL이 사용되는 곳에는 어디나 사용할 수 있으며 이를 사용하여 파일을 직접 읽을 수 있습니다. 위에 있는 예제는 파일로 부터 직접 이미지를 읽어서 사용자에게 바로 표시합니다. 이미지 적재는 http URL로 부터 로딩될 때 정상적인 ‘load’ 이벤트처럼 동작하며 ‘error’이벤트는 필요한 경우 적절히 발생합니다.

iframe의 src 속성의 값으로 File.url의 반환 값을 지정하면 HTML 파일도 표시할 수 있습니다. 한가지 주의할 점은 HTML 파일안의 상대적 URL은 File.url에 의해 생성된 URL에 맞춰 상대적으로 동작하지 않는다는 것입니다. 이는 의도적인 것으로 사용자에게 단지 HTML 파일만 접근하는 것을 허용하고 이미지 파일들에는 접근하지 못하게 하기 위해서입니다.

이 URL이 유용하게 쓰일 수 있는 또 다른 곳은 CSS 배경 이미지 부분으로 엘리먼트의 배경을 로컬 파일로 지정하는 것입니다. 또한 기존의 코드가 XMLHttpRequest사용하고 있고, 이 부분을 FileReader로 바꾸고 싶지 않다면 이 URL을 그대로 XMLHttpRequest에 사용할 수 있습니다.

FireFox 베타 1이 지원하는 또 다른 기능은 FormData 객체입니다. 이 객체는 기존에 multipart/form-data 인코딩을 사용하여 파일을 전송받는 서버가 있는 경우 유용합니다.

Firefox 3.6에서는 파일을 XMLHttpRequest를 사용하여 multipart/form-data 인코딩으로 서버로 전송하는데 어느 정도의 수작업이 필요합니다. FileReader를 사용하여 파일의 내용을 메모리로 읽어들여야하며, 수동으로 multipart/form-data 인코딩을 한 후에 마지막으로 서버로 전송해야 합니다. 이러한 조건은 보다 많은 코드를 필요로 하고 또한 파일 전체 내용을 메모리로 읽어들이는 것을 요구합니다.

Firefox 4에서는 XMLHttpRequest 레벨 2명세에 따라 FormData 객체를 사용할 수 있습니다. 그래서, 다음과 같은 깔끔한 코드를 사용할 수 있습니다.

var fd = new FormData();

fd.append("fileField", myFile);
var xhr = new XMLHttpRequest();

xhr.open("POST", "file_handler.php");
xhr.send(fd);

이 코드는 파일을 자동으로 multipart/form-data 인코딩하여 서버로 전송합니다. 파일의 내용은 작은 부분씩 읽히며 그렇기 때문에 매우 많은 메모리를 사용하지 않습니다. FormData를 사용하면 같은 내용을 다음과 같은 폼으로도 전송할 수 있습니다.

<form enctype="multipart/form-data" method="post">
  <input type="file" name="fileField">

</form>

다중 파일을 전송하고 싶은 경우에는 전송을 원하는 파일들 각각에 대해 간단히 fd.append를 호출하면 됩니다. 그러면, 파일들은 하나의 요청안에서 모두 전송됩니다. 물론 XMLHttpRequest가 항상 제공하는 업로드나 다운로드 방법도 그대로 사용할 수 있습니다.

FormData에는 또 하나의 멋진 기능이 있습니다. 정상적이고 파일이 아닌 multipart/form-data 값들 또한 전송할 수 있습니다. 예를 들어 다음과 같습니다.

var fd = new FormData();
fd.append("author", "Jonas Sicking");

fd.append("name", "New File APIs");
fd.append("attachment1", file1);
fd.append("attachment2", file2);

var xhr = new XMLHttpRequest();
xhr.open("POST", "file_handler.php");

xhr.send(fd);

심지어 <form>에 있는 모든 정보를 가지고 있는 FormData 객체를 얻을 수도 있습니다(하지만, 이와 관련된 구문은 최종 버전에서 변경될 여지가 있습니다).

var fd = myFormElement.getFormData();

var xhr = new XMLHttpRequest();
xhr.open("POST", "file_handler.php");

xhr.send(fd);

여기에서 fd는 폼에 속해있는 모든 요소들(입력 필드, 라디오 버튼, 파일 필드 등등)의 데이터를 포함하고 있습니다.

항상 그렇듯이 저희는 이 기능에 대한 피드백에 귀를 기울이고 있습니다. 여러분이 생각하고 있는 것들과 특별히 테스트 결과나 원하는대로 결과가 나오는 않는 경우들을 저희에게 알려주세요. 피드백을 위해 http://www.mozilla.com/en-US/firefox/beta/feedback/를 사용하거나 오른쪽 구석에 있는 피드백 버튼(아래 이미지를 보세요)을 사용해 주세요.

원저자: Christopher Blizzard – 원문으로 가기

작성자: Kim, Myung Shin

Kim, Myung Shin가 작성한 문서들…


댓글이 없습니다.

댓글 쓰기