XMLHttpRequest로 파일과 매개변수를 함께 전송하기
JavaScript에서 XMLHttpRequest(XHR)를 사용해 서버에 데이터를 보낼 때, 파일과 일반 텍스트 매개변수를 하나의 요청에 함께 담아야 하는 경우가 자주 있습니다. 이럴 때 가장 간단하고 표준적인 방법은 FormData 객체를 활용하는 것입니다.
FormData는 HTML 폼(form)과 동일한 key-value 형식으로 데이터를 구성할 수 있게 해주는 내장 객체로, 파일(File 또는 Blob)과 문자열·숫자 매개변수를 손쉽게 섞어서 전송할 수 있습니다.
기본 예제 코드
var myForm = new FormData();
myForm.append('param1', 'demo');
myForm.append('param2', 6767);
myForm.append('myDir', 'public-data');
myForm.append('demofile', file);
xhr.send(myForm);
코드 단계별 설명
1. FormData 객체 생성
new FormData()로 비어 있는 폼 데이터 객체를 만듭니다. 이 객체가 곧 전송될 요청 본문(body)이 됩니다.
2. append()로 필드 추가
append(키, 값) 메서드를 사용해 원하는 만큼의 매개변수를 추가합니다. 위 예제에서는 문자열('demo', 'public-data')과 숫자(6767)를 추가했습니다.
3. 파일 추가
append('demofile', file)처럼 세 번째 인자 위치에 File 또는 Blob 객체를 넣으면 파일이 그대로 포함됩니다. 파일은 보통 다음과 같이 파일 입력 요소에서 가져옵니다:
var fileInput = document.querySelector('input[type="file"]');
var file = fileInput.files[0];
4. send()로 전송
xhr.send(myForm)을 호출하면 FormData가 자동으로 multipart/form-data 형식으로 직렬화되어 서버로 전송됩니다.
완전한 XHR 설정 예제
실제 동작하려면 XMLHttpRequest 객체를 미리 열고(open) 콜백을 등록해 두어야 합니다:
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);
xhr.onload = function () {
if (xhr.status === 200) {
console.log('업로드 성공:', xhr.responseText);
} else {
console.error('업로드 실패:', xhr.status);
}
};
var myForm = new FormData();
myForm.append('param1', 'demo');
myForm.append('param2', 6767);
myForm.append('myDir', 'public-data');
myForm.append('demofile', file);
xhr.send(myForm);
주의 사항
FormData를 전송할 때는 Content-Type 헤더를 직접 설정하지 마세요. 브라우저가 boundary 값을 포함한 올바른 multipart/form-data 헤더를 자동으로 지정해 주기 때문입니다. 임의로 설정하면 요청이 정상적으로 처리되지 않을 수 있습니다.
또한 최신 프로젝트라면 Promise 기반의 fetch() API나 Axios 같은 라이브러리도 동일하게 FormData를 지원하므로, 상황에 맞게 선택하면 됩니다. 하지만 레거시 환경이나 업로드 진행률(progress) 이벤트 처리가 필요한 경우에는 XMLHttpRequest가 여전히 유용한 선택입니다.