혼합 콘텐츠(mixed content) 경고 해결
HTTPS 페이지의 혼합 콘텐츠 경고가 생기는 이유와 능동/수동 리소스별 해결 방법.
HTTPS로 잘 서비스되던 페이지인데 주소창 자물쇠가 안 뜨거나 “안전하지 않음”으로 바뀌고, 콘솔에는Mixed Content 경고가 줄줄이 찍힌 적이 있을 겁니다. 이건 인증서가 잘못된 게 아니라,HTTPS 페이지가 내부적으로 HTTP 리소스를 불러오고 있다는 신호입니다. 페이지 본문은 암호화돼 있는데 그 안의 이미지·스크립트·CSS 일부가 평문 HTTP로 전송되면, 브라우저는 그 페이지를 더 이상 “완전히 안전”하다고 보지 않습니다.
이 문제를 “혼합 콘텐츠(mixed content)”라고 부릅니다. 방치하면 자물쇠가 사라지는 미관 문제로 끝나지 않습니다. 능동적 혼합 콘텐츠는 최신 브라우저에서 아예 차단되어 스크립트나 스타일이 적용되지 않고, 결과적으로 레이아웃이 깨지거나 기능이 죽습니다. 이 가이드는 혼합 콘텐츠가 정확히 무엇인지, 어디서 새는지 찾는 법, 그리고 유형별 해결책을 실제 예시와 함께 정리합니다.
능동(active) vs 수동(passive) 혼합 콘텐츠
모든 혼합 콘텐츠가 똑같이 취급되지는 않습니다. 브라우저는 그 리소스가 페이지를 얼마나 통제할 수 있는지에 따라 두 부류로 나눕니다. 능동 콘텐츠는 페이지 전체를 조작할 수 있어 곧바로 차단되고,수동 콘텐츠는 표시 영역만 바꿀 수 있어 차단 대신 경고로 표시됩니다.
| 유형 | 대표 리소스 | 브라우저 동작 |
|---|---|---|
| 능동(active) | <script>, <iframe>, <link rel="stylesheet">, fetch()/XHR, 웹폰트 | 차단됨 — 아예 로드되지 않음. 콘솔에 “blocked” 오류. |
| 수동(passive) | <img>, <audio>, <video>, <object> 일부 | 로드는 되지만 경고 표시 — 자물쇠가 사라지고 콘솔에 경고. |
핵심은 이렇습니다. 자물쇠만 사라졌다면 보통 이미지 같은 수동 리소스가 범인이고, 스타일이 깨지거나 버튼이 동작하지 않는다면 차단된 능동 리소스(CSS·JS)가 범인입니다.
새는 곳 찾기
고치려면 먼저 어떤 HTTP 요청이 페이지에 섞여 있는지 정확히 알아야 합니다. 두 가지를 병행하세요.
- 브라우저 개발자 도구: F12로 콘솔을 열면 차단·경고된 항목이 전체 URL과 함께 표시됩니다. Network 탭에서
http://요청만 필터링해도 한눈에 보입니다. - 페이지 전체 스캔: 콘솔은 “지금 화면에 로드된” 것만 보여주므로, 클릭해야 나오는 리소스나 동적으로 주입되는 자원을 놓치기 쉽습니다. 페이지 단위로 한 번에 점검하려면 혼합 콘텐츠 검사로 HTML을 스캔해 HTTP 참조를 빠짐없이 목록화하는 편이 안전합니다.
유형별 해결책
찾았다면 대부분 다음 세 가지로 정리됩니다.
http://를https://로 바꾸기 — 가장 기본이자 권장 방법. 해당 리소스가 HTTPS를 지원하는지 먼저 직접https://로 열어 확인한 뒤 교체하세요.- 프로토콜 상대 경로(
//host/asset.js)는 피하기 — 한때 흔하던 방식이지만 이제는 권장하지 않습니다. 모든 사이트가 HTTPS인 지금은 명시적으로https://를 적는 편이 의도가 분명하고 디버깅도 쉽습니다. Content-Security-Policy: upgrade-insecure-requests로 일괄 승격 — 본문 HTML을 전부 손볼 수 없을 때 안전망이 됩니다. 이 지시어는 페이지가 요청하는http://URL을 브라우저가 요청 직전에 자동으로https://로 끌어올려 줍니다. 보안 헤더 설정은 보안 헤더 검사로 적용 여부를 확인할 수 있습니다.
실전 예시: HTTPS 페이지의 HTTP 이미지
https://shop.example.com 상품 페이지에 다음 마크업이 있다고 합시다.
- 문제 코드:
<img src="http://cdn.example.com/p/1.jpg"> - 증상: 이미지는 보이지만 주소창 자물쇠가 사라지고, 콘솔에
Mixed Content: ... was loaded over HTTP경고. - 1차 확인: 브라우저에서
https://cdn.example.com/p/1.jpg를 직접 열어 정상 표시되는지 본다. - 정석 수정:
<img src="https://cdn.example.com/p/1.jpg">—s하나만 더하면 끝. - 대량 대응: 본문 곳곳에 같은 패턴이 흩어져 있으면, 응답 헤더에
Content-Security-Policy: upgrade-insecure-requests를 추가해 한꺼번에 승격.
수정 후에는 강력 새로고침(Ctrl+Shift+R)으로 캐시를 비우고 자물쇠가 정상으로 돌아왔는지, 그리고 다시 혼합 콘텐츠 검사로 남은 HTTP 참조가 0인지 확인하면 마무리됩니다.