AJAX 대신 XMLHttpRequest 사용해서 파일 다운로드 기능 구현하기
서버에 요청해 받은 파일로 파일 다운로드 기능을 구현해야 하는데, 회사에서 사용하고 있는 JQuery 버전이 낮아 JQuery AJAX로는 구현할 수 없었습니다. 때문에 JQuery AJAX 대신 XMLHttpRequest를 사용해 해결하였으며 이번 기회에 XMLHttpRequest에 대해 정리해보고자 합니다.
XMLHttpRequest란?
XMLHttpRequest는 JavaScript에서 HTTP 요청을 보내는 JavaScript 객체입니다. 이 객체를 사용하여 서버와 통신하고, 서버로부터 데이터를 받아올 수 있습니다.
XMLHttpRequest를 사용하면 JavaScript를 사용하여 웹 페이지의 동적인 부분을 업데이트할 수 있습니다. 예를 들어, 사용자가 어떤 작업을 수행하면, XMLHttpRequest를 사용하여 서버와 통신하고, 데이터를 가져와서 페이지를 업데이트할 수 있습니다. 이 방법을 사용하면 페이지를 다시 로드하지 않아도 새로운 정보를 가져올 수 있습니다. 또한, XMLHttpRequest를 사용하여 파일을 다운로드하면, 다운로드 진행 상황을 추적하거나 중단하는 등의 기능을 추가할 수 있습니다.
기본 코드
var xhr = new XMLHttpRequest();
xhr.open('GET', '<http://example.com>', true);
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
console.log(this.responseText);
}
};
xhr.send();
위 코드에서 xhr.open()
메서드의 첫 번째 매개변수는 HTTP 메서드 (GET, POST 등)를, 두 번째 매개변수는 요청을 보낼 URL을, 세 번째 매개변수는 비동기 여부를 나타냅니다. onreadystatechange
이벤트 핸들러에서는 요청의 상태가 XMLHttpRequest.DONE
이며 응답 상태 코드가 200일 때 responseText
속성을 통해 응답 데이터를 가져옵니다.
AJAX로 파일 다운로드 구현이 안 되는 이유
AJAX는 브라우저 내부에서 동작하는 JavaScript를 사용하여 비동기적으로 서버와 통신하는 기술입니다. 이때, 브라우저의 보안 정책으로 인해 파일 다운로드 기능이 구현되지 않을 수 있습니다. 브라우저는 AJAX 요청에서 반환된 데이터를 보안상의 이유로 로컬 파일 시스템에 직접 접근할 수 없습니다. 따라서 AJAX를 사용하여 파일을 다운로드하려면, 위에서 설명한 XMLHttpRequest를 사용하는 방법으로 해결해야 합니다.
XMLHttpRequest로 파일 다운로드 기능 구현
XMLHttpRequest를 사용하여 파일을 다운로드하려면 responseType
속성을 "blob"
으로 설정하고, onload
이벤트 핸들러에서 URL.createObjectURL()
을 사용하여 Blob 객체의 URL을 생성해야 합니다. 아래는 파일 다운로드를 위한 예시 코드입니다.
var xhr = new XMLHttpRequest();
var url = 'http://example.com/file.pdf';
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status === 200) {
var blob = new Blob([this.response], { type: 'application/pdf' });
var downloadUrl = URL.createObjectURL(blob);
var a = document.createElement("a");
a.href = downloadUrl;
a.download = 'file.pdf';
document.body.appendChild(a);
a.click();
}
};
xhr.send();
위 코드에서 xhr.open()
메소드의 첫 번째 매개변수는 HTTP 메서드 (GET, POST 등)를, 두 번째 매개변수는 요청을 보낼 파일의 URL을, 세 번째 매개변수는 비동기 여부를 나타냅니다.
responseType
속성을 "blob"
으로 설정하여 Blob 객체로 데이터를 받아옵니다.
onload
이벤트 핸들러에서 Blob
객체를 생성하고, URL.createObjectURL()
을 사용하여 Blob 객체의 URL을 생성합니다. 그리고 생성된 URL로 <a>
요소를 생성하여 download
속성을 설정한 후, click()
메소드를 호출하여 다운로드를 시작합니다.
blob
Blob은 바이너리 데이터의 불변성 버퍼입니다. 파일, 이미지, 오디오 또는 기타 바이너리 데이터를 나타낼 수 있습니다. 이러한 데이터를 Blob 객체로 만들면, URL.createObjectURL()을 사용하여 해당 Blob 객체의 URL을 생성할 수 있습니다. 이 URL은 이미지 태그의 src 속성 또는 다운로드 링크의 href 속성 등에서 사용할 수 있습니다.
XMLHttpRequest 지원 중단?
XMLHttpRequest는 최신 브라우저에서는 더 이상 권장되지 않는 기술이지만, 이전 버전과의 호환성을 위해 계속해서 지원될 예정입니다. 사실 Fetch API가 더 최신이며 더 권장되는 방법이므로, 가능하면 Fetch API를 사용하는 것이 좋습니다.
하지만 실무에서 사용하는 JavaScript나 JQuery 버전이 낮다면 XMLHttpRequest를 불가피하게 사용해야 할 수 있습니다.
XMLHttpRequest VS. Fetch API
- XMLHttpRequest는 비동기적으로 서버와 통신하는 JavaScript 객체입니다. 반면에 Fetch API는 Promise 기반으로 비동기적으로 서버와 통신합니다.
- XMLHttpRequest는 요청과 응답을 다루는 방법이 불편합니다. 반면에 Fetch API는 간결하고 편리하게 요청과 응답을 다룰 수 있습니다.
- XMLHttpRequest는 크로스 도메인 요청에 대한 보안 정책을 우회하기 위해 CORS를 사용해야 합니다. Fetch API는 기본적으로 CORS를 지원합니다.
- XMLHttpRequest는 업로드와 다운로드 진행 상황을 추적하기 위해 복잡한 코드가 필요합니다. 반면에 Fetch API는 진행 상황을 추적하는 기능을 제공하지 않습니다.
- XMLHttpRequest는 오래된 기술이므로, Fetch API가 더 최신이며 더욱 권장되는 방법입니다.