본문 바로가기
DevOps

“Swiper is not defined”와 “Mixed Content” 오류, IIS

by Rainbound-IT 2025. 10. 17.
반응형

웹 서비스를 운영하다 보면 "같은 코드인데 어떤 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. 원인 정리

  1. Swiper 파일이 HTTP 경로로 지정되어 브라우저에서 차단됨
  2. 그 결과 Swiper 객체가 로드되지 않아 Swiper is not defined 오류 발생
  3. 일부 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. 검증 단계

  1. 브라우저 캐시 비활성화
    • DevTools → Network → “Disable cache” 체크 후 새로고침(Ctrl+F5)
  2. Network 탭 확인
    • swiper.min.css, swiper.min.js 요청이 https://로 표시되고, Status 200 인지 확인
  3. Console 탭 확인
    • Mixed Content 또는 Swiper is not defined 오류가 사라졌는지 확인
  4. 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만 허용하게 지시하는 것”입니다.

 

반응형

댓글