웹 브라우저의 Mixed Content 차단 정리

인턴일지

목록 보기
2/7
post-thumbnail

상황 정리

구분내용
프론트Vite로 빌드 → 결과물(dist)을 백엔드 서버에 업로드
배포 주소https://배포주소/admin (프론트 화면), https://배포주소/docs (백엔드 Swagger 같은 API Docs)
백엔드이미 HTTPS 적용되어 있음
API 호출프론트에서 http://api.domain.com 같은 주소로 호출
문제프론트 화면은 HTTPS로 제공되는데, API는 HTTP로 호출 → Mixed Content 에러 발생

문제 파악

  1. 브라우저는 https:// 로 불러온 페이지에서 http:// 요청을 차단함.

  2. Vite 빌드한 프론트엔드 코드에서 API Base URL이 http://api.domain.com 으로 설정되어 있었음.

  3. 결과적으로:

    브라우저는 "야 HTTPS 페이지인데 왜 HTTP로 API를 부르냐" → Mixed Content 차단.

    콘솔에 Mixed Content: The page at 'https://배포주소/admin' was loaded over HTTPS, but requested an insecure resource 'http://api.domain.com/endpoint'. This request has been blocked; the content must be served over HTTPS.

⇒ 근본적으로는 프론트 빌드 시 API BASE URL이 HTTP로 고정되어 있고 프론트용 배포 서버나 CICD구축이 되어있지 않는 상태에서 백엔드 경로 밑 /admin(엔드포인트만 다르게 설정)으로 빌드된 걸 배포함으로써 발생한 문제였다.

해결 방법

[🔶 Content-Security-Policy (CSP)의 upgrade-insecure-requests 디렉티브 활용]

<meta charset="UTF-8" http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"/>

  • HTTP → HTTPS 자동 업그레이드 명령으로 HTML의 로 설정하면, 서버가 아니라 클라이언트 쪽에서 강제로 바꿔준다.

  • Mixed Content를 CSP level에서 브라우저가 자동 보정해주는 방식"을 택해서 해결

  • 코드 수정/배포 프로세스를 건드릴 수 없을 때 쓰는 응급처치지만, 표준 기술(CSP)로 서버가 HTTPS 대응만 되어 있다면 매우 유효한 해결법

[🔶 동작 예시]

[🔶 실무에서는 이걸 언제 써?]

  • 레거시 프로젝트에서 급하게 HTTPS로 배포하는데 코드 수정할 시간이 없을 때.
  • CDN 이미지, 외부 리소스 HTTP 링크가 박혀있고 단기간에 수정 불가능할 때.
  • API 엔드포인트 https 전환이 이미 끝났지만 프론트 코드가 하드코딩된 경우 임시로.

[🔶 단점]

항목내용
서버가 https 미지원이면 그대로 에러서버가 https 대응 안 하면 Mixed Content 에러 대신 404 or 연결 실패
브라우저가 무조건 https로 바꾸기 때문에 예상치 못한 문제 가능개발 환경이나 프록시에서 http만 되는 상황에서는 오히려 방해
클린 아키텍처 관점에서는 "핵심 코드 수정 없이 UI 메타로 우회"하는 꼼수장기적으로는 환경변수, 빌드 프로세스 정비가 정답

+) 프론트 배포 시 BASE_URL을 app.mount 기준을 맞추는 이유

  • 브라우저가 리소스를 어디서 찾을지(base)와, Vue가 어디서부터 라우팅할지(app.mount, router base)가 일치해야 제대로 확인 가능하다.

1. URL 경로가 꼬이기 때문

  • 배포 시 프론트가 https://domain.com/admin/ 밑에 들어갈 때, vite base를 /admin/로 안 맞추면 빌드된 js, css가 루트(/) 기준으로 잡혀버린다.

    • 예시로,
      vite.config.js에서 base 설정이 이렇게 안 되어있으면base: '/':
      빌드 결과물의 js, css는 /assets/main.js, /assets/style.css 로 되어버려서 404 에러가 뜬다.
  • /admin/ 밑에 배포 시, base: '/admin/',로 설정해야 정확한 경로에서 요청을 할 수 있다.

2. app.mount와 배치 경로가 안 맞으면 SPA 라우팅도 꼬임

  • Vue나 React SPA에서는 브라우저 주소창을 통해 내부 라우팅(/admin/something)을 하게 됨.
  • vite base가 /admin/로 설정되어 있지 않으면:
    • 리소스 로딩 실패 (css, js 못 찾음)
    • History 모드 라우팅 실패 (404 나거나 엉뚱한 URL 이동)

[🔶 app.mount와 base 경로의 관계]

항목역할
app.mount('#app')index.html 내 특정 DOM element에 Vue App을 마운트
base: '/admin/'빌드 시 정적 자원(js, css 등)의 경로를 /admin/ 기준으로 맞춤
둘 다 일치시키는 이유실제 배포 경로(/admin)에 맞게 리소스 경로 + 라우팅 경로를 일관성 있게 유지

참고 자료: https://velog.io/@yuna-c/ERROR-HTTPS-HTTP-%ED%86%B5%EC%8B%A0-%EB%B6%88%EA%B0%80%EC%9B%B9-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-Mixed-Content-%EC%B0%A8%EB%8B%A8

profile
밝은 미래 FE 개발자의 기록

0개의 댓글