Base64 이미지가 안 보인다고요? 흔한 10가지 원인과 해결법
2026년 4월 28일 · 8분 읽기
이미지를 Base64로 변환하고 data URI를 HTML에 넣었는데… 아무것도 안 나옵니다. 깨진 이미지 아이콘만 덩그러니. 더 황당한 건 Chrome에서는 잘 되는데 Safari에서는 안 되고, 로컬에선 되는데 배포하면 안 되는 경우죠.
Base64 이미지 표시 실패가 짜증나는 이유는 문자열이 겉으로 봐선 멀쩡해 보이기 때문입니다. 진짜 원인은 디테일에 숨어 있죠 — 프리픽스에서 글자 하나 빠졌거나, 복사-붙여넣기 과정에서 보이지 않는 공백이 끼어들었거나, 백엔드가 몰래 이중 인코딩을 한 경우입니다. 이 글에서 10가지 원인 모두를 코드 예시와 해결법과 함께 다룹니다.
속성 점검표: 증상 → 원인 → 해결
여기서부터 시작하세요. 증상을 찾고, 원인을 파악한 다음, 아래 상세 해결법으로 이동하세요.
| # | 증상 | 원인 | 해결법 |
|---|---|---|---|
| 1 | 404 / 깨진 아이콘 | data: 프리픽스 누락 | data:image/...;base64, 추가 |
| 2 | 빈 화면 / 렌더링 안 됨 | ; 대신 , 오타 | 프리픽스의 세미콜론 수정 |
| 3 | 빈 화면 / 렌더링 안 됨 | base64 뒤 쉼표 누락 | 쉼표 추가: base64, |
| 4 | 이미지 잘림 / 깨짐 | 문자열 잘림(truncation) | TEXT 컬럼 타입 사용 |
| 5 | InvalidCharacterError | 공백 / 잘못된 문자 혼입 | str.replace(/\s/g, '') |
| 6 | 코드에선 정상, HTML에선 깨짐 | 줄바꿈 \n 오염 | \r\n 제거 |
| 7 | 브라우저마다 동작이 다름 | 패딩 = 누락 | URL 인코딩 또는 패딩 보완 |
| 8 | 대부분 정상 작동 | MIME 타입 불일치 | 고치는 게 맞지만 원인은 아님 |
| 9 | 깨진 아이콘, 문자열이 ~33% 김 | 이중 인코딩 | 불필요한 인코딩 단계 제거 |
| 10 | 깨진 아이콘, 문자열에 \/ | JSON / URL 이스케이프 오염 | JSON.parse() 사용 |
프리픽스 오류: data: URI 형식이 잘못됨
data URI 스킴은 문법이 엄격합니다. 한 글자만 틀려도 브라우저는 Base64 문자열을 이미지 데이터가 아닌 잘못된 URL로 취급합니다.
원인 1: data URI 프리픽스가 통째로 빠짐
data:image/...;base64, 프리픽스 없이 Base64 문자열을 src에 바로 넣으면, 브라우저는 이를 상대 URL 경로로 해석하여 404가 발생합니다.
❌ <img src="iVBORw0KGgo..." />
✅ <img src="data:image/png;base64,iVBORw0KGgo..." /> 원인 2: 세미콜론을 쉼표로 오타
data:image/png;base64,... 대신 data:image/png,base64,...로 작성하면, 브라우저는 base64,...를 Base64 인코딩 지시가 아닌 일반 텍스트 콘텐츠로 처리합니다.
❌ data:image/png,base64,iVBORw0KGgo...
✅ data:image/png;base64,iVBORw0KGgo... 원인 3: "base64" 뒤에 쉼표 누락
base64와 실제 데이터 사이의 쉼표는 필수입니다. data:image/png;base64iVBOR...처럼 생략하면, 브라우저는 base64iVBOR...를 문자셋 이름으로 해석합니다.
❌ data:image/png;base64iVBORw0KGgo...
✅ data:image/png;base64,iVBORw0KGgo... 인코딩 손상: Base64 문자열 자체가 깨짐
프리픽스가 정확하더라도 인코딩된 데이터가 저장, 전송 또는 복사-붙여넣기 과정에서 조용히 손상될 수 있습니다.
원인 4: 문자열 잘림
데이터베이스 컬럼에 글자 수 제한(예: VARCHAR(65535))이 있으면 Base64 문자열이 조용히 잘립니다. 100KB PNG는 Base64로 약 136,000자 — 65,535에서 잘리면 디코딩된 이미지는 완전히 깨집니다. 해결: Base64 저장에는 TEXT 또는 LONGTEXT 타입을 사용하세요.
원인 5: 잘못된 문자 혼입 (공백, 특수문자)
유효한 Base64는 A-Z, a-z, 0-9, +, /, =만 사용합니다. 복사-붙여넣기 시 끼어든 공백은 atob()에서 InvalidCharacterError를 발생시킵니다. 해결: 사용 전 모든 공백 제거: str.replace(/\s/g, '').
원인 6: 줄바꿈 오염
openssl base64는 기본적으로 76자마다 \n을 삽입합니다(RFC 2045). 이 줄바꿈은 HTML data URI를 깨뜨립니다. 해결: openssl base64 -A(한 줄 출력) 사용, 또는 줄바꿈 제거: str.replace(/[\r\n]/g, '').
원인 7: URL 파싱에서 패딩이 사라짐
Base64 끝의 패딩 문자 =는 URL 파라미터를 거치면 사라지기 쉽습니다(=는 URL 예약 문자). 패딩 없이도 동작하는 브라우저와 그렇지 않은 브라우저가 있어 환경 간 동작이 달라집니다. 해결: URL에 넣기 전 encodeURIComponent() 사용, 또는 수신 측에서 패딩 보완.
MIME 타입 불일치: 정말 깨질까?
의외겠지만 잘못된 MIME 타입을 선언해도 대부분의 경우 이미지는 정상적으로 표시됩니다.
원인 8: 선언된 MIME과 실제 파일 형식 불일치
data:image/png;base64,/9j/4AAQ...(JPEG 데이터에 PNG MIME 선언)로 작성해도 대부분의 모던 브라우저는 콘텐츠 스니핑으로 정상 렌더링합니다. 다만 두 가지 경우에 문제됩니다: (1) 엄격한 CSP에서 MIME 강제 적용, (2) 서버 측에서 선언된 MIME 기반 포맷 변환 수행. 결론: 고치는 게 맞지만 표시 실패의 진짜 원인인 경우는 드뭅니다.
파이프라인 오류: 브라우저에 도달하기 전에 이미 깨짐
이 유형이 가장 진단하기 어렵습니다 — 코드 상의 Base64 문자열은 멀쩡해 보이는데, 직렬화나 전송 과정에서 손상이 발생하기 때문입니다.
원인 9: Base64 이중 인코딩
백엔드가 이미 인코딩된 데이터를 한 번 더 Base64 인코딩하면, Base64 문자열의 Base64가 생성됩니다. 길이가 예상보다 ~33% 길어지고, 한 번 디코딩해도 바이너리 이미지가 아닌 텍스트가 나옵니다. 감별법: 한 번 디코딩하여 결과가 또 Base64처럼 보이면(영문자로 시작, =로 끝남) 이중 인코딩입니다. 해결: 백엔드 처리 과정에서 불필요한 인코딩을 제거하세요.
원인 10: JSON 이스케이프 또는 URL 인코딩 오염
Base64 문자열에는 /가 포함됩니다. 일부 JSON 직렬화기는 이를 \/로 이스케이프합니다. 프론트엔드에서 JSON.parse 없이 원시 문자열을 그대로 사용하면 불필요한 백슬래시가 데이터를 오염시킵니다. 마찬가지로 URL 파라미터로 Base64를 전달하면 +는 공백이 되고 =는 사라집니다. 해결: JSON 데이터에는 반드시 JSON.parse()를 사용. URL 전송 시 encodeURIComponent() 사용.
체계적 디버깅 템플릿
위 원인 중 해당되는 게 없다면 다음 순서로 하나씩 점검하세요:
- 브라우저 주소창에서 data URI 테스트 — 전체
data:image/...;base64,...문자열을 주소창에 직접 붙여넣습니다. 표시되면 애플리케이션의 문자열 주입 방식에 문제가 있는 겁니다. - 브라우저 콘솔 확인 — F12를 눌러 Console 탭에서
net::ERR_INVALID_URL이나 CSP 위반 오류를 찾습니다. - 문자열 길이 비교 — 소스(백엔드)와 프론트엔드에서 받은 Base64 문자열 길이를 비교합니다. 차이가 있으면 전송 중 잘림이나 손상입니다.
- 디코딩 후 검사 — 콘솔에서
atob()로 첫 몇 글자를 디코딩합니다.InvalidCharacterError가 발생하면 잘못된 문자가 혼입된 겁니다. - 이중 인코딩 감지 — 한 번 디코딩합니다. 결과가 또 Base64처럼 보이면 한 번 더 디코딩합니다. 두 번째 디코딩에서 바이너리 데이터가 나오면 처리 파이프라인에 불필요한 인코딩 단계가 있는 겁니다.
ViewJSON으로 Base64 즉시 검증
Base64 문자열을 수동으로 검사하는 대신, JSON을 ViewJSON에 붙여넣으세요. 매직 넘버 감지로 Base64 인코딩 미디어를 자동 식별하여 인라인 미리보기를 표시합니다 — 미리보기가 뜨면 유효한 Base64, 안 뜨면 어떤 필드가 깨졌는지 정확히 알 수 있습니다.
관련 기사
JSON API 응답 내 Base64 이미지를 디버깅하는 가장 우아한 방법 →지금 바로 사용해 보세요
Base64 문자열을 붙여넣고, 올바르게 렌더링되는지 즉시 확인하세요 — 브라우저에서 바로, 업로드 없이.
ViewJSON 열기 →