웹 서비스를 운영하다 보면 "같은 코드인데 어떤 PC에서는 정상, 어떤 PC에서는 오류"처럼
정확한 원인이 헷갈리는 문제가 종종 발생합니다.
이번 글은 실제로 AWS ALB + Windows VM(IIS) 환경에서
Swiper is not defined 및 Mixed Content 오류가 일부 PC에서만 발생했던 문제를
코드 수정 없이 인프라 레벨에서 완벽히 해결한 기록입니다.
🧠 1. 증상 요약
🧩 콘솔 오류 메시지
common.js?v=1745305927:39 Uncaught ReferenceError: Swiper is not defined
at Object.TopnavScroll (common.js?v=1745305927:39:9)
at Object.init (common.js?v=1745305927:7:14)
at HTMLDocument.<anonymous> (common.js?v=1745305927:1122:17)
이 오류는 Swiper 객체가 정의되기 전에 호출되었을 때 발생합니다.
즉, Swiper 라이브러리가 로드되지 않았거나,
로드 순서가 잘못되었거나,
브라우저에서 JS 파일을 차단한 경우입니다.
⚙️ 2. 환경 구조
사용자 브라우저 (HTTPS)
│
▼
AWS ALB (443)
│
▼
Windows VM (IIS)
- ALB는 HTTPS 트래픽을 수신
- ALB → IIS 구간은 내부 HTTP
- HTML 내부에는 다음과 같은 코드가 존재했습니다:즉, HTTP 리소스가 섞여 있었던 것입니다.
⚡ 3. 두 번째 오류 — Mixed Content
콘솔에는 다음과 같은 메시지도 함께 떴습니다.
(index):42 Mixed Content: The page at '<https://example.dev.site/>'
was loaded over HTTPS, but requested an insecure stylesheet
'<http://example.dev.site/swiper/css/swiper.min.css>'.
This request has been blocked; the content must be served over HTTPS.
이는 브라우저가 HTTPS 페이지 안에서 HTTP 리소스 로드를 보안상 차단했기 때문입니다.
즉, Swiper.js와 CSS가 로드되지 않아 “Swiper is not defined”로 이어진 것이었습니다.
🕵️ 4. 이상한 점 — 왜 어떤 PC는 되고, 어떤 PC는 안 될까?
같은 코드임에도 일부 PC에서만 오류가 나는 이유는 다음 중 하나였습니다.
원인 설명
| 🔧 사이트 설정 차이 | 어떤 PC는 “안전하지 않은 콘텐츠 허용” 옵션이 활성화됨 |
| 🧱 브라우저 정책 차이 | Chrome/Edge 버전에 따라 HTTPS 정책 강화 여부 상이 |
| 💾 캐시/서비스워커 | HTTPS로 캐시된 리소스를 쓰는 PC vs 새로 HTTP 요청하는 PC |
| 🧩 보안 소프트웨어/확장 프로그램 | 일부 확장이 HTTP 요청 차단 또는 우회 |
| 🌐 DNS/프록시 차이 | 같은 도메인이 다른 서버(테스트 환경 등)로 향함 |
즉, 환경별로 HTTP 리소스 처리 정책이 달라 발생한 비일관성 문제였습니다.
🧩 5. 원인 정리
- Swiper 파일이 HTTP 경로로 지정되어 브라우저에서 차단됨
- 그 결과 Swiper 객체가 로드되지 않아 Swiper is not defined 오류 발생
- 일부 PC는 캐시 또는 허용 설정 덕분에 통과 → “어떤 PC만 된다” 현상 발생
🛠️ 6. 해결 전략 — 코드 수정 없이 인프라로 처리
단계 위치 목적
| 1️⃣ | ALB | HTTP → HTTPS 리다이렉트 |
| 2️⃣ | IIS | CSP 헤더(upgrade-insecure-requests) 추가 |
| 3️⃣ | IIS (선택) | URL Rewrite로 X-Forwarded-Proto 기반 HTTPS 강제 |
6.1 ALB: HTTP 요청 리다이렉트
ALB 리스너에서 80 포트의 요청을 443으로 리다이렉트합니다.
✅ 콘솔 설정
- Listener :80
- Action → Redirect
- Protocol: HTTPS
- Port: 443
- Status code: HTTP_301
✅ CLI 예시
aws elbv2 create-listener \\
--load-balancer-arn <ALB_ARN> \\
--protocol HTTP --port 80 \\
--default-actions Type=redirect,RedirectConfig='{"Protocol":"HTTPS","Port":"443","StatusCode":"HTTP_301"}'
💡 이렇게 하면 사용자가 http://로 접근해도 자동으로 https://로 이동합니다.
6.2 IIS: 브라우저에게 HTTPS 업그레이드 지시 (CSP + HSTS)
🧩 핵심 헤더
- Content-Security-Policy: upgrade-insecure-requests
- → 브라우저가 HTML 내의 모든 HTTP 리소스를 HTTPS로 자동 변환
- Strict-Transport-Security: max-age=31536000; includeSubDomains
- → 브라우저가 향후에도 항상 HTTPS로 연결하도록 기억
✅ web.config 설정
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Content-Security-Policy" value="upgrade-insecure-requests" />
<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
💡 효과
- HTML 내부가 여전히 http://여도 브라우저가 자동으로 https:// 요청으로 교체
- 외부 CDN, 내부 정적 리소스 모두 안전하게 로드
- 모든 PC에서 정책이 동일하게 적용됨
6.3 IIS: URL Rewrite (보조 방어)
ALB → IIS 구간은 내부 HTTP일 수 있기 때문에,
IIS가 “사용자가 HTTPS로 접근했는지” 직접 감지하지 못할 수 있습니다.
이를 위해 ALB가 전달하는 X-Forwarded-Proto 헤더를 사용합니다.
✅ web.config 설정
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Force HTTPS by XFP" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_X_FORWARDED_PROTO}" pattern="^https$" negate="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
이 규칙은 HTTPS가 아닌 경우 자동으로 HTTPS로 리다이렉트합니다.
6.4 (보조) HTML 리소스 치환 (최후의 수단)
템플릿 수정이 어려운 구형 환경이라면, IIS에서 Outbound Rules 또는 Reverse Proxy로
응답 본문 내의 http://example.dev.site/를 https://example.dev.site/로 치환할 수 있습니다.
단, 성능상 오버헤드가 크므로 CSP 업그레이드 방식이 우선입니다.
🔍 7. 검증 단계
- 브라우저 캐시 비활성화
- DevTools → Network → “Disable cache” 체크 후 새로고침(Ctrl+F5)
- Network 탭 확인
- swiper.min.css, swiper.min.js 요청이 https://로 표시되고, Status 200 인지 확인
- Console 탭 확인
- Mixed Content 또는 Swiper is not defined 오류가 사라졌는지 확인
- Response Headers
- 서버 응답에 Content-Security-Policy 와 Strict-Transport-Security 존재 확인
✅ 8. 최종 결과
항목 결과
| Mixed Content 오류 | ✅ 사라짐 |
| Swiper.js 로드 실패 | ✅ 정상 동작 |
| 모든 PC 동작 일관성 | ✅ 동일한 HTTPS 경로로 로드 |
| 보안 수준 | ✅ 강화 (HSTS + CSP 적용) |
🧾 9. 최종 구성 요약
구성 요소 위치 역할
| ALB | AWS | 80 → 443 리다이렉트 |
| IIS | VM | CSP/HSTS 헤더 추가로 HTTPS 업그레이드 |
| IIS URL Rewrite | (선택) | 내부 HTTP 환경 보조 리다이렉트 |
| Swiper.js | 정적 자원 | HTTPS로 로드되는지 확인 |
🧩 10. 교훈 & 베스트 프랙티스
- 문제의 근본 원인:
- Swiper JS/CSS가 HTTP로 불러와져 Mixed Content 차단 → JS 객체 미정의
- 환경별로 달리 보였던 이유:
- 각 PC의 브라우저 정책/캐시/보안설정 차이 때문
- 결정적 해결책:브라우저가 모든 HTTP 요청을 HTTPS로 자동 업그레이드하도록 유도
- Content-Security-Policy: upgrade-insecure-requests 헤더 적용으로
- 보조책:
- ALB 리다이렉트 + HSTS + URL Rewrite로 HTTPS 정책을 인프라 전반에 강제
💬 11. 결론
이 사례는 “코드 한 줄 수정 없이” 인프라만으로 HTTPS 불일치 문제를 해결한 전형적인 사례입니다.
✅ 핵심 요약
- ALB : HTTP → HTTPS 리다이렉트
- IIS : CSP(업그레이드 요청) + HSTS
- (옵션) : URL Rewrite로 이중 보호
이 조합만으로, 브라우저/정책/환경에 상관없이
모든 사용자에게 일관된 HTTPS 리소스 제공이 가능해졌습니다.
💡 참고: 이 구성은 AWS ALB + IIS 뿐 아니라
Nginx, Apache, CloudFront 환경에도 동일하게 적용할 수 있습니다.
핵심은 “서버에서 HTTPS만 응답하게 만들고, 브라우저에 HTTPS만 허용하게 지시하는 것”입니다.
'DevOps' 카테고리의 다른 글
| Argo CD에서 GitHub Apps로 보안 강화하기 (0) | 2025.10.29 |
|---|---|
| Githup Apps 이란? 활용방법과 token과 비교 (0) | 2025.10.29 |
| 클라우드 계정이 다른 개발 / 운영 환경의 CIDR 범위 설정 (0) | 2025.10.10 |
| [kafka] 토픽을 파티션으로 나누는 이유 (0) | 2025.09.29 |
| 퍼센타일 지표(p50, p90)로 보는 성능과 모니터링 (0) | 2025.09.24 |
댓글