이번에 회사에서
axios
사용해서 excel 파일 다운로드를 구현하는 개발을 진행했다
그 과정에서 공부하고 배운 내용을 정리해보려 한다😊
백엔드에서 요구한 내용
POST
로 통신Content-Disposition
헤더에서 파일명을 추출axios
POST
톺아보기axios.post(url[, data[, config]])
params
전송api 통신 할 때, 매개변수로 데이터를 전달하는 방식❗
params
속성을 사용하여 전달할 데이터를 객체 형태로 지정
const url = [ 백엔드 통신 api url ]
axios.post(url, null, { params: { key1: value1, key2: value2 } })
URLSearchParams()
사용하기( URLSearchParams 필요성에 대한 부연설명은 뒤에 )
const params = new URLSearchParams();
params.append('key1', value1);
params.append('key2', value2);
params.toString();
axios.post(url, null, { params });
URLSearchParams()
객체의 append()
메서드를 이용해서 파라미터를 하나씩 추가toString()
메서드 사용url?key1=value1&key2=value2
data
에 직접 담아 보내기 data
속성에 데이터를 담은 객체를 전달한다
대용량의 데이터나 구조화된 데이터를 전송할 때 유용👍🏻
const data = {
key1: value1,
key2: value2,
};
axios.post(url, data);
URLSearchParams
객체의 필요성쿼리스트링은 url에서 경로명( pathname ) 다음에 나오는 ?
기호로 시작하는 문자열이다
검색, 필터링, 페이지네이션, 정렬 등 다양한 용도로 사용된다
일반적으로, 웹 서버는 url 쿼리스트링을 분석해서 작업을 수행한다
여러 개의 key와 value의 쌍을 &
기호로 구분하여 매개변수를 나타낸다
url?key1=value1&key2=value2&...
길이가 너무 길어져서 읽기가 어렵다💩
만약 다국어나 특수 문자가 포함되어 있으면 인코딩 작업도 필요하다😥
URL API에서 제공하는 URLSearchParams()
를 사용하면 수월하게 쿼리스트링을 다룰 수 있다❗
excel
파일 다운로드 코드 설명const url = [ 백엔드 통신 api url ]
const data = [
{ key1: value1 }
];
// excel 파일 다운로드 요청
const response = await axios.post(url, data, {
responseType: 'blob', // 파일 데이터를 Blob으로 받기 위해 설정
});
responseType
을 blob
으로 설정하여 응답을 Blob 객체
로 받는다Blob 객체
는 파일 데이터와 같은 바이너리 데이터를 나타내는 객체이다 ( 여기서는 excel 파일을 의미❗ )// Content-Disposition 헤더에서 파일 이름 추출
const disposition = response.headers['content-disposition'];
let fileName = 'initialFileName.xlsx'; // 기본 파일 이름
// filename이 존재하는 확인
if (disposition?.indexOf('filename=') !== -1) {
const fileNameMatch = disposition.match(/filename="([^"]*)"/);
if (fileNameMatch && fileNameMatch[1]) {
// URL 인코딩된 파일 이름을 디코딩
fileName = decodeURIComponent(fileNameMatch[1]);
}
}
response.headers['content-disposition']
: 서버 응답 헤더에서 Content-Disposition
값을 가져온다disposition.match(/filename="([^"]*)"/)
: 정규 표현식을 사용하여 filename="파일명"
형식으로 되어 있는 부분 추출match()
메서드를 통해 문자열이 정규식과 일치하는 부분을 검색한다match()
메서드는 문자열이 정규식과 일치하면, 일치하는 전체 문자열을 첫 번째 요소로 포함하는 Array를 반환한다 ( 나의 경우, fileNameMatch[0]에는 "filename=파일명.xlsx"
이, fileNameMatch[1]에는 "파일명.xlsx"
만 담겨있어서 개발 편의성을 위해 배열 index 1의 값을 사용했다❗ )decodeURIComponent()
: URL 인코딩된 파일 이름을 decodeURIComponent()
를 사용하여 디코딩한다 // Blob 데이터를 URL로 변환
const linkUrl = window.URL.createObjectURL(
new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
);
Blob
데이터를 사용해 브라우저에서 사용할 수 있는 임시 url을 생성한다 ( 이 url은 나중에 파일을 다운로드하는 데 사용된다 )Blob
객체` 를 생성한다response.data
는 서버에서 받은 바이너리 데이터이다 ( == Blob
데이터 )application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
: excel 파일 형식에 맞는 MIME 타입
이다 // 링크 생성
const link = document.createElement('a');
link.href = linkUrl;
link.setAttribute('download', fileName); // 다운로드할 파일 이름 설정
// 링크 클릭하여 다운로드 트리거
document.body.appendChild(link);
link.click();
document.createElement('a')
: 다운로드 링크 ( <a>
태그 )를 동적으로 생성한다link.href = linkUrl
: 위에서 생성한 Blob url
을 href
속성에 할당한다link.setAttribute('download', fileName)
: download
속성을 설정한다 ( 파일을 다운로드할 때 파일 이름을 지정 )document.body.appendChild(link)
: link를 html <body>
에 추가link.click()
: 프로그램적으로 link 클릭하여 excel 파일을 다운로드한다// 링크 삭제 및 메모리 정리
document.body.removeChild(link);
window.URL.revokeObjectURL(linkUrl);
🔹 필요없는 자원은 메모리에서 정리해주기 🔹
( 자원은 비싸니까...😥 )
document.body.removeChild(link)
: 프로그램적 link 클릭이 완료된 후, link를 DOM에서 제거한다window.URL.revokeObjectURL(linkUrl)
: createObjectURL()
로 생성된 임시 url을 해제한다 ( url로 인한 메모리 점유 해제 )MIME 타입
MIME 타입
은 웹에서 파일의 형식과 내용을 식별하는 데 사용된다
( Microsoft Excel에서 사용하는 최신 스프레드시트 형식 )
MIME 타입
설명application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
application
: 파일의 주된 유형 ( 데이터 형식을 의미 )vnd
: Vendor 의 약자로, 특정 공급업체나 표준을 나타낸다openxmlformats-officedocument
: Open XML 형식의 문서 파일.xlsx
, .docx
, .pptx
등 다양한 문서 파일 형식에 사용된다spreadsheetml.sheet
: excel 스프레드시트 파일 형식을 지정한다 ( .xlsx
파일 확장자를 가진 excel 파일 )MIME
타입의 사용파일 다운로드 : 웹 애플리케이션에서 사용자가 파일을 다운로드할 때, MIME
타입을 설정하여 브라우저가 파일을 올바르게 처리하고 적절한 프로그램으로(예: excel) 다운로드한다
응답 헤더: 서버에서 클라이언트로 파일을 전송할 때, Content-Type
헤더를 통해 파일의 MIME 타입
을 명시한다
클라이언트는 이 정보를 바탕으로 파일을 처리한다