어느 날부터 서비스에서 CSS가 간헐적으로 안 먹는 현상이 생겼다
콘솔을 보면 CORS 관련 에러가 뜨고, 화면은 스타일이 빠진 채로 깨져 보였다
힘들었던 포인트는 이거였다
- 어떤 브라우저에서는 안 터지고
- 어떤 브라우저/디바이스에서는 터지고
- 같은 환경에서도 가끔은 되고, 가끔은 실패
원인 파악이 너무 어려웠다.
결론
우리는 써드파티 라이브러리/CSS를 버저닝 + 캐싱 목적 때문에 회사 S3에 올려두고, 서비스에서는 그 S3 주소로 직접 로드하고 있었다.
그런데 <link>로 CSS를 불러올 때 예전에 넣어둔
crossorigin="anonymous"
이 속성 때문에, 브라우저가 CSS를 CORS 모드로 요청하면서 간헐적인 CORS 에러가 발생했다.
그래서 나는 crossorigin="anonymous"를 제거했고, 그 뒤로 문제는 멈췄다
당시 구조 (문제의 시작)
대략 이런 식이었다
- third-party.css 같은 파일을 S3에 업로드
- 서비스 HTML에서는 S3 URL로 바로 로드
<link
rel="stylesheet"
href="https://{우리S3도메인}/third-party/xxx/v123/third-party.css"
crossorigin="anonymous"
/>
그리고 어느 순간부터, 일부 환경에서 CSS 로드가 실패하면서 CORS 에러가 터졌다
왜 ‘간헐적’이었나?
나는 처음에 S3 CORS 설정을 의심했다
근데 "항상"이 아니라 "간헐적"이어서 더 헷갈렸다
결론적으로 내 케이스는 crossorigin 속성 때문에 요청 모드가 달라지는 상황이 섞여서 체감이 랜덤처럼 보였던 거였다
- 어떤 상황에서는 정상 응답/캐시된 응답으로 넘어가서 문제 없어 보이고
- 어떤 상황에서는 CORS 체크가 빡세게 걸리면서 실패
특히 S3/캐시/CDN이 섞인 환경에서는 응답이 200/304/리다이렉트/에러 응답 등으로 갈릴 수 있고,
그 중 일부 응답에 CORS 헤더가 빠져 있으면 브라우저가 막아버리는 경우가 생길 수 있다.
(내가 겪은 건 “정확히 언제”라기보다 "어떤 응답이 걸리느냐"에 따라 달라졌던 느낌)
결정적 힌트: <link>의 crossorigin이 CORS 요청을 강제한다
구글링하다가 아래 글을 보고 방향이 잡혔다
요약하면 이런 느낌이다
- crossorigin 속성이 있으면 브라우저가 CORS 모드로 리소스를 요청한다
- 그러면 서버(S3)가 Access-Control-Allow-Origin 같은 헤더로 허용해줘야 한다
- 허용이 안 되면 브라우저가 “안 가져온 것처럼” 막아버린다
나는 CSS를 “그냥 적용만” 하면 되는 상황이었고,
crossorigin="anonymous"를 붙여둘 이유가 딱히 없었다.
해결: crossorigin="anonymous" 제거
문제의 속성을 제거했다
Before
<link
rel="stylesheet"
href="https://{우리S3도메인}/third-party/xxx/v123/third-party.css"
crossorigin="anonymous"
/>
After
<link
rel="stylesheet"
href="https://{우리S3도메인}/third-party/xxx/v123/third-party.css"
/>
이렇게 바꾸고 나서, 내가 겪던 간헐적 CORS 에러/스타일 미적용 현상이 사라졌다
주의: crossorigin이 필요한 경우도 있음
이 글의 요지는 "무조건 빼라"가 아니라,
왜 붙여둔 건지 목적을 확인하자는 거다.
예를 들면 이런 경우에는 crossorigin이 필요할 수 있다
- 브라우저가 리소스를 검증하려면 CORS가 필요해지는 케이스가 있음
- JS에서 stylesheet 내용(cssRules)을 접근하려는 경우 (CORS 허용이 필요)
그런 목적이 있다면, 속성을 빼는 대신
- S3(또는 CloudFront)에서 CORS 헤더가 항상 붙도록 설정을 정리
하는 게 맞다.
하지만 나처럼 "그냥 CSS 적용"만 목적이라면,
불필요한 crossorigin 때문에 오히려 장애 포인트가 될 수 있다.
마무리
정리하면,
- 써드파티 CSS를 S3에 올려서 서비스에서 직접 로드하는 구조에서
- <link>에 crossorigin="anonymous"가 붙어 있으면
- 브라우저가 CORS 모드로 가져오면서 간헐적으로 막히는 상황이 생길 수 있다
나처럼 증상이 랜덤하게 보이면 더 헤매기 쉬우니,
일단 <link>에 crossorigin이 붙어 있는지부터 확인해보는 걸 추천한다
'FrontEnd > web' 카테고리의 다른 글
| [실무 기록] 렌더링 차단(Render‑blocking) 줄이려고 preconnect / preload를 썼는데… 진짜 뭐가 좋아지나? (0) | 2026.03.06 |
|---|---|
| [실무 기록] (2탄) macOS에서 adb가 "개발자 신원을 확인할 수 없습니다"로 막혀 Chrome Inspect가 또 안 될 때 (0) | 2026.03.05 |
| [실무 기록] Chrome Inspect에서 Pending authentication만 뜨고 안드로이드 디버깅이 안 될 때 (0) | 2026.01.12 |
| [실무 기록] 웹뷰 브릿지, 이거 누가 책임져야 하지? (0) | 2025.12.10 |
| 검색 엔진 크롤링과 자바스크립트 렌더링 정리 (3) | 2025.09.08 |
