문제 발생 원인
파일을 바이너리 문자열(binary string)로 읽은 뒤 multipart/form-data 요청을 직접 수동으로 구성하면, 디스크에 저장된 원본 파일보다 훨씬 크거나 내용이 다른 파일이 만들어질 수 있습니다.
이러한 현상은 바이너리 데이터를 문자열 형태로 변환하는 과정에서 인코딩 불일치나 데이터 왜곡이 발생하기 때문입니다. 특히 이미지처럼 바이너리 기반의 파일에서 자주 나타납니다.
해결 방법
가장 안전한 방법은 xhr.send(File) 또는 xhr.send(FormData)를 사용하는 것입니다. 이 방식은 브라우저가 multipart/form-data 본문을 알아서 올바르게 구성해 주기 때문에 데이터 손상 없이 파일을 전송할 수 있습니다.
또한 업로드 진행 상황이 필요하다면 xhr의 progress 이벤트를 함께 활용하면 됩니다. 해당 이벤트는 목록의 모든 항목이 이미 생성된 이후에 발생하므로, 진행률 표시 로직을 이 시점에 연결하는 것이 좋습니다.
업로드 함수 예제
다음은 FormData와 XMLHttpRequest를 활용한 업로드 함수 예시입니다.
function display(url, files) {
var myForm = new FormData();
for (var j = 0, file; file = files[j]; ++j) {
myForm.append(file.name, file);
}
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = function(e) { ... };
xhr.send(myForm);
}이처럼 파일을 직접 문자열로 다루지 않고 FormData 객체에 담아 전송하면, 원본 파일과 동일한 크기와 내용을 유지한 채 안정적으로 업로드할 수 있습니다.