서버 없이 자바스크립트로 파일 생성해서 셀프 다운로드 하기

자바스크립트를 이용하면 별도의 웹서버 기능 없이도 파일을 생성해서 다운로드할 수 있습니다.

텍스트 기반인 파일은 종류에 상관없이 생성할 수 있습니다.

HTML5 표준을 지원하는 웹 브라우저에서는 모두 지원되는 표준 기능이며, 하이퍼링크 태그(<a>)의 "href" 속성을 활용해서 구현합니다.

"href" 속성은 하이퍼링크 태그를 통해 이동하는 URI를 표시하는 속성입니다.

대상 링크는 다른 HTML 문서일 수도 있고, 이미지나 사운드와 같은 리소스 파일이거나 텍스트 파일일 수도 있습니다.

그리고 하이퍼링크 태그에는 새로운 HTML5 속성이 하나 더 있습니다. 하이퍼링크 태그에 "download" 속성을 표시하면 하이퍼링크로 가리키는 연결된 페이지, 또는 리소스 파일을 웹 브라우저에서 열지 않고 파일로 다운로드합니다.

"href" 속성과 "download 속성의 특징을 이용해 리소스에 해당되는 데이터를 자바스크립트로 생성해서 다운로드를 할 수 있습니다.

먼저 하이퍼링크 태그 요소를 하나 생성한 후 "href" 속성에 다음과 같이 텍스트 데이터를 붙여 넣습니다.

"href" 속성에 적용하는 값은 URI가 되어야 하지만 다음과 같이 "data:text/plain;charset=utf-8," + 문자열 텍스트로 속성 값을 명시하면 링크를 대신해서 속성 값으로 붙여 넣은 텍스트 데이터를 직접 열게 됩니다.

let element = document.createElement('a');
let text = '테스트파일';
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));

그리고 하이퍼링크 요소에 "download" 속성을 추가합니다.

다운로드 속성은 값으로 파일 이름을 명시할 수 있습니다. 파일 이름을 속성에 명시하면 원래 파일 이름 대신 명시한 파일 이름으로 파일이 다운로드됩니다.

하이퍼링크 태그 "href"에 추가한 데이터는 파일 이름이 없기 때문에 반드시 "download" 속성에 다운로드할 파일 이름을 명시해야 합니다.

element.setAttribute('download', '파일이름.txt');

이제 다운로드 할 준비는 모두 되었습니다.

이제 생성한 하이퍼링크 요소를 웹페이지에 붙인 후 클릭해서 이벤트를 트리거하면 "href"로 붙인 텍스트 파일이 다운로드됩니다.

이때 주의할 점이 있습니다.

붙여 넣은 하이퍼링크는 클릭해서 이벤트를 트리거해야 합니다.

이런 번거로움을 피하려면 하이퍼링크 요소를 웹페이지에 붙여넣은 후 클릭 이벤트를 자바스크립트로 발생시켜서 사용자가 하이퍼링크를 클릭해서 다운로드하는 번거로움을 줄여줄 수 있습니다.

element.style.display = 'none'; //하이퍼링크 요소가 보이지 않도록 처리
document.body.appendChild(element); //DOM body요소에 하이퍼링크 부착
element.click(); //클릭 이벤트 트리거 - 이 시점에 다운로드 발생
document.body.removeChild(element); //하이퍼링크 제거

웹페이지에 자바스크립트 코드를 붙여 넣어서 자동으로 "파일이름.txt" 파일이 다운로드되도록 코드를 완성합니다.

document.addEventListener('DOMContentLoaded', ()=>{
	let element = document.createElement('a');
	let text = '테스트파일';
	element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
	element.setAttribute('download', 'download.txt');
	element.style.display = 'none'; //하이퍼링크 요소가 보이지 않도록 처리
	document.body.appendChild(element); //DOM body요소에 하이퍼링크 부착
	element.click(); //클릭 이벤트 트리거 - 이 시점에 다운로드 발생
	document.body.removeChild(element); //하이퍼링크 제거
})

작성한 코드를 활용해서 현재 웹페이지의 HTML 소스 전체를 다운로드하는 함수(downloadTemplate())를 작성하면 다음과 같이 만들 수 있습니다.

document.addEventListener('DOMContentLoaded', ()=>{
    downloadTemplate('source.html', document.documentElement.outerHTML); //현재 웹페이지 전체 소스 선택
})        

//Download HTML Template Source
function downloadTemplate(filename, text) {
    let element = document.createElement('a');
    element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
    element.setAttribute('download', filename);

    element.style.display = 'none';
    document.body.appendChild(element);

    element.click();

    document.body.removeChild(element);
}

iOS 계열 모바일 기기에서는 웹 브라우저에서 다운로드하는 것을 허용하고 있지 않기 때문에 이 기능을 사용할 수 없으므로 사용전 호환성 체크를 하고 사용해야 합니다.