[실무 기록] 브라우저 캐시와 CORS 에러

2026. 3. 6. 19:26·FrontEnd/web

페이지 이동할 때만 간헐적으로 터지던 그 CORS, 왜 강력 새로고침하면 사라졌을까

가끔 이런 경우가 있다.

처음 들어왔을 때는 멀쩡하다.
직접 URL을 치고 들어와도 정상이다.
그런데 어떤 페이지를 거쳐 다른 페이지로 이동하면, 갑자기 CSS나 폰트에서 CORS 에러가 난다.

심지어 더 헷갈리는 건 Ctrl + Shift + R로 강력 새로고침하면 또 멀쩡해진다는 점이다.

처음에는 preload가 문제인가 싶었고, 브라우저 캐시가 어딘가 꼬였나 싶기도 했는데, 결론부터 말하면 핵심은 preload 자체가 아니라 같은 URL을 서로 다른 방식으로 요청하고 있었다는 점이었다.

이번 글은 페이지 이동 시 간헐적으로 발생하던 CORS 에러를 추적하면서, 왜 이런 현상이 생겼는지 정리해 둔 기록이다.


결론 먼저

핵심만 먼저 정리하면 이렇다.

  • 같은 리소스 URL을 페이지마다 crossorigin 다르게 쓰면 문제가 생길 수 있다.
  • 브라우저는 이 차이를 단순히 같은 요청으로 보지 않는다.
  • CDN까지 끼어 있으면, 먼저 캐시된 응답이 이후 CORS 요청에도 재사용되면서 에러가 날 수 있다.
  • 강력 새로고침하면 사라지는 이유도 결국 캐시 우회 때문이다.
  • preload는 근본 원인이라기보다, 있으면 더 빨리 문제를 드러내는 증폭 요인에 가깝다.

문제 상황

에러는 이런 식이었다.

Access to CSS at 'https://cdn.example.com/assets/common.css'
from origin 'https://www.example.com' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

이상했던 포인트는 두 가지였다.

  1. 항상 터지지 않았다.
    처음 진입할 때는 정상인 경우가 많았고, 특정 이동 경로에서만 간헐적으로 재현됐다.
  2. 강력 새로고침하면 사라졌다.
    같은 페이지, 같은 리소스인데 Ctrl + Shift + R 이후 다시 보면 또 멀쩡했다.

이쯤 되면 보통 이런 생각이 든다.

  • preload가 문제인가?
  • 브라우저 캐시가 꼬였나?
  • CDN이 이상한 응답을 주는 건가?
  • 서버가 ACAO 헤더를 어떤 때만 주는 건가?

실제로 원인은 이 요소들이 얽혀 있었는데, 시작점은 생각보다 단순했다.


시작점: crossorigin 유무가 같아 보여도 같지 않다

같은 CSS를 아래처럼 불러온다고 해보자.

<!-- A: crossorigin 없음 -->
<link rel="stylesheet" href="https://cdn.example.com/common.css">

<!-- B: crossorigin="anonymous" 있음 -->
<link rel="stylesheet" href="https://cdn.example.com/common.css" crossorigin="anonymous">

 

겉으로 보면 둘 다 같은 CSS를 불러오는 코드처럼 보인다.
그런데 브라우저 입장에서는 이 둘이 완전히 같은 요청이 아니다.

정리하면 이렇게 볼 수 있다.

방식 요청 성격
crossorigin 없음 일반적으로 no-cors 쪽으로 처리
crossorigin="anonymous" 있음 cors 방식으로 처리

그리고 cors 방식으로 요청이 들어가면 서버 응답에 Access-Control-Allow-Origin 헤더가 있어야 브라우저가 그 응답을 정상적으로 받아들인다.

즉, 같은 URL이라도 브라우저는 단순히 “한 번 받아 온 파일” 정도로 보지 않고, 어떤 모드로 요청했는지까지 포함해서 다르게 취급한다.


여기서 진짜 문제가 시작된다

프로젝트 안에 레이아웃이 둘 있었고, 같은 CSS 파일을 서로 다르게 로드하고 있었다고 해보자.

<!-- 레이아웃 A (crossorigin 없음) -->
<link rel="stylesheet" href="https://cdn.example.com/common.css">

<!-- 레이아웃 B (crossorigin 있음) -->
<link rel="stylesheet" href="https://cdn.example.com/common.css" crossorigin="anonymous">

이 상태에서 페이지 이동이 일어나면 흐름이 이렇게 된다.

1) 먼저 crossorigin 없는 페이지를 방문

<link rel="stylesheet" href="https://cdn.example.com/common.css">

이 요청은 CORS 요청이 아니라는 쪽으로 처리된다.
즉, 서버 입장에서도 Origin 헤더를 기준으로 별도 응답을 줄 필요가 없는 요청처럼 보일 수 있다.

그래서 CDN은 ACAO 헤더 없는 응답을 그냥 캐시해 둔다.

2) 그다음 crossorigin="anonymous"가 있는 페이지로 이동

<link
  rel="stylesheet"
  href="https://cdn.example.com/common.css"
  crossorigin="anonymous"
/>

 

이제는 브라우저가 CORS 요청으로 본다.
즉, 이번에는 Access-Control-Allow-Origin이 필요하다.

그런데 CDN 쪽에는 이미 같은 URL에 대한 응답이 캐시돼 있다. 문제는 그 캐시가 이전 no-cors 성격 요청 기준으로 저장된 응답일 수 있다는 점이다.

그러면 CDN은 예전에 저장한 응답을 그대로 내주고, 그 응답에는 ACAO 헤더가 없다.

결과는 간단하다.

  • 브라우저: “이번 요청은 CORS인데?”
  • 응답: “ACAO 없음”
  • 결과: CORS 에러

그래서 “간헐적”으로 보였던 거다

문제가 발생하려면 순서가 중요하다.

  • 먼저 crossorigin 없는 방식으로 해당 URL이 캐시되어야 하고
  • 그 뒤에 같은 URL을 crossorigin="anonymous"로 다시 요청해야 한다

즉, 유저가 어떤 경로로 먼저 들어왔는지에 따라 에러가 나기도 하고 안 나기도 한다.

그래서 이슈가 더 짜증 난다.

  • 처음 진입하면 정상
  • 다른 페이지를 거쳐 오면 에러
  • 새 탭으로 열면 또 정상

이런 식으로 보이면 사람 입장에서는 “재현이 안 되는 랜덤 버그”처럼 느껴지기 쉽다.


강력 새로고침하면 왜 멀쩡해졌나

이것도 결국 캐시 때문이다.

강력 새로고침을 하면 브라우저가 기존 캐시를 그대로 믿지 않고 리소스를 다시 확인하거나 새로 받아오게 된다.

그 과정에서 이번 요청은 crossorigin="anonymous"가 붙은 CORS 요청이니까, 서버나 origin이 정상적으로 ACAO 헤더를 포함해서 응답하면 그제야 브라우저 입장에서 말이 맞아 떨어진다.

즉, 강력 새로고침이 문제를 “고친” 게 아니라, 기존에 꼬여 있던 캐시 경로를 우회해서 정상 응답을 다시 받아온 것에 가깝다.


CDN이 끼면 왜 더 헷갈리나

여기서 한 단계 더 들어가면 Vary: Origin 얘기가 나온다.

핵심은 이것이다.

CDN은 응답 전체를 캐시하는데, 응답이 Origin 값에 따라 달라질 수 있다는 사실을 알려주지 않으면 그냥 같은 URL이면 같은 응답이라고 생각하기 쉽다.

즉, Vary: Origin이 없으면 아래 같은 상황이 생길 수 있다.

  • Origin 없이 들어온 요청 응답을 캐시
  • 나중에 Origin 헤더가 있는 요청이 와도
  • CDN은 그냥 “같은 URL이네?” 하고 예전 응답 반환
  • 브라우저는 “이건 CORS 응답이어야 하는데?” 하고 차단

반대로 Vary: Origin이 제대로 설정돼 있으면 Origin 값에 따라 캐시를 분리해서 볼 수 있어서 이런 충돌 가능성을 줄일 수 있다.


그럼 preload가 원인이었나

이건 많이 헷갈리는 부분인데, 결론은 이렇다.

preload 자체가 근본 원인은 아니다.

다만 preload가 있으면 문제를 더 빨리, 더 안정적으로 터뜨리는 쪽으로 작용할 수는 있다.

예를 들어 preload가 먼저 no-cors 쪽으로 해당 리소스를 잡아 버리면, 뒤에서 실제 stylesheet가 CORS 방식으로 요청될 때 이미 캐시가 좋지 않은 상태로 선점되어 있을 수 있다.

그래서 preload가 있으면 체감상 “preload를 넣은 뒤부터 CORS가 생긴 것처럼” 보일 수 있다.

하지만 실제로는 그 전에 같은 URL에 대해 crossorigin 일관성이 깨져 있던 상태가 먼저 문제다.

정리하면 이렇게 보면 된다.

 

항목 역할
crossorigin 불일치 근본 원인
preload 증상 증폭 가능

실무에서 제일 중요한 규칙

가장 중요한 원칙은 하나다.

같은 URL은 프로젝트 전체에서 같은 crossorigin 정책으로 로드해야 한다

예를 들어 아래처럼 쓰면 위험하다.

<!-- layout-a -->
<link rel="stylesheet" href="https://cdn.example.com/common.css">

<!-- layout-b -->
<link
  rel="stylesheet"
  href="https://cdn.example.com/common.css"
  crossorigin="anonymous"
/>

이런 식으로 같은 파일을 서로 다르게 로드하면 페이지 이동, 프리로드, 캐시, CDN이 겹치는 순간 문제를 만들 가능성이 커진다.

그래서 아래처럼 통일하는 게 맞다.

<!-- layout-a -->
<link
  rel="stylesheet"
  href="https://cdn.example.com/common.css"
  crossorigin="anonymous"
/>

<!-- layout-b -->
<link
  rel="stylesheet"
  href="https://cdn.example.com/common.css"
  crossorigin="anonymous"
/>

이건 stylesheet만의 문제가 아니라 preload, script, font 같은 외부 리소스에도 비슷하게 적용해서 보는 게 안전하다.


preload와 실제 태그의 crossorigin도 맞춰야 한다

이것도 놓치기 쉽다.

<!-- 안 좋은 예 -->
<link rel="preload" as="style" href="...common.css">
<link rel="stylesheet" href="...common.css" crossorigin="anonymous">

이렇게 되면 preload와 실제 사용 태그가 브라우저 입장에서 같은 요청으로 보이지 않을 수 있다.

그래서 preload를 쓸 거면 실제 사용 태그와 맞춰 주는 편이 안전하다.

<!-- 좋은 예 -->
<link
  rel="preload"
  as="style"
  href="...common.css"
  crossorigin="anonymous"
/>
<link
  rel="stylesheet"
  href="...common.css"
  crossorigin="anonymous"
/>

배포할 때는 버전 파라미터가 꽤 중요하다

여기서 한 가지 더 중요한 포인트가 있다.

실무에서는 종종 같은 회사가 운영하는 정적 자산 서버나 CDN을 쓰게 된다.
소유권 기준으로는 내부 인프라처럼 느껴질 수 있지만, 브라우저는 그런 걸 알지 못한다. 브라우저는 도메인이 다르면 cross-origin으로 본다.

즉,

  • 우리 서비스 페이지 도메인
  • 우리 회사가 운영하는 정적 CDN 도메인

이 둘이 다르면 브라우저 입장에서는 그냥 교차 출처 요청이다.

여기서 중요한 건 origin 서버가 원래부터 CORS 응답을 줄 수 있느냐이다.

만약 강력 새로고침 이후에는 정상 복구된다면, 그건 보통 이런 뜻이다.

  • origin 서버는 원래 Access-Control-Allow-Origin을 반환할 수 있다
  • 그런데 중간 CDN이 예전에 캐시한 ACAO 없는 응답을 계속 내주고 있다

즉, 문제의 본질은 origin이 CORS를 지원하지 않는 것이 아니라, CDN이 잘못 캐시된 구버전 응답을 계속 서빙하는 상황일 수 있다.

이럴 때 가장 단순하고 강한 해결책이 버전 파라미터다.

<link
  rel="stylesheet"
  href="https://cdn.example.com/common.css?v=1.0.1"
  crossorigin="anonymous"
/>

URL이 바뀌면 브라우저와 CDN은 그걸 새 리소스로 본다.

즉,

  • 구버전 URL: common.css?v=1.0.0
  • 신버전 URL: common.css?v=1.0.1

이 둘은 별개다.

그래서 신버전 URL은 CDN 입장에서 처음 보는 요청이 되고, origin에서 응답을 새로 가져오게 된다. 이때 origin이 원래 ACAO를 반환하도록 설정되어 있다면, CDN은 이번엔 ACAO가 포함된 응답을 새로 캐시하게 된다.

정리하면 버전 파라미터는 단순히 파일 내용을 최신화하는 용도만이 아니라,

  • 기존 잘못 캐시된 응답과 충돌을 끊고
  • CDN이 새 응답 헤더까지 다시 받아오게 만드는

효과도 있다.

다만 전제는 분명하다.

버전 파라미터가 해결하는 경우

  • 예전에 no-cors 성격으로 캐시된 응답이 남아 있는 경우
  • origin 서버는 원래 ACAO를 정상적으로 반환하는 경우
  • URL만 새로 만들면 CDN이 새 응답을 다시 받아올 수 있는 경우

버전 파라미터로 해결되지 않는 경우

  • origin 서버가 ACAO 헤더를 아예 반환하지 않는 경우
  • CDN 자체가 해당 리소스에 대해 CORS 응답을 제대로 전달하지 못하는 경우
  • 실제 배포에서 버전값이 바뀌지 않아 URL이 그대로인 경우

즉, ?v=나 ?t=는 새 URL을 만들기 때문에 효과가 있는 것이지, 값이 그대로면 아무 의미가 없다.


고정 URL 리소스는 따로 봐야 한다

문제가 더 까다로워지는 건 버전 파라미터를 붙이지 않고 고정 URL로 쓰는 리소스다.

예를 들면 외부 라이브러리 CSS를 아래처럼 고정 경로로 쓰는 경우다.

<link rel="preload" href="https://cdn.example.com/libs/owl.carousel.min.css" as="style">

이 상태에서 단순히 crossorigin="anonymous"만 추가해서 배포하면 어떻게 될까?

<link
  rel="preload"
  href="https://cdn.example.com/libs/owl.carousel.min.css"
  as="style"
  crossorigin="anonymous"
>

 

문제는 URL이 그대로라는 점이다.

CDN 입장에서는 같은 URL이므로 예전에 캐시된 응답을 그대로 줄 수 있다.
즉, origin 서버가 지금은 ACAO를 줄 수 있어도, CDN을 통과하지 못하면 브라우저는 여전히 ACAO 없는 응답을 받게 된다.

그래서 이런 고정 URL 리소스는 일반적으로 세 가지 방식 중 하나로 대응한다.

A. 버저닝 추가

가장 단순한 방법이다.

<!-- 수정 전 -->
<link rel="preload" href="https://cdn.example.com/libs/owl.carousel.min.css" as="style">

<!-- 수정 후 -->
<link
  rel="preload"
  href="https://cdn.example.com/libs/owl.carousel.min.css?v=1"
  as="style"
  crossorigin="anonymous"
>

 

이렇게 하면 CDN은 새 URL을 처음 보는 요청으로 처리하고, origin에서 파일 내용뿐 아니라 응답 헤더까지 포함한 전체 응답을 다시 가져온다.

즉,

  • 새 URL → CDN 캐시 미스
  • origin 재요청
  • ACAO 포함 응답 수신
  • CDN이 정상 응답으로 새 캐시 생성

이 흐름이 된다.

실무에서는 라이브러리 파일 내용이 바뀐 게 아니라 단지 캐시 우회가 목적일 수도 있으니, 주석이나 커밋 메시지에 버전값 추가 이유를 남겨 두는 것도 좋다.

B. CDN 캐시 Purge

URL을 바꾸지 않기로 했다면, 배포와 동시에 해당 리소스의 CDN 캐시를 강제로 비워야 할 수도 있다.

다만 이 방법은 일회성 대응에 가깝다.

왜냐하면 purge 이후에도 다시 no-cors 성격 요청이 먼저 들어오면, ACAO 없는 응답이 또 캐시될 수 있기 때문이다.

즉, purge만으로는 재발 가능성을 완전히 없애기 어렵다.

C. Vary: Origin 설정

URL을 바꾸지 않고 장기적으로 해결하려면 Vary: Origin이 필요하다.

이 헤더는 CDN에게 Origin 값에 따라 캐시를 분리해서 보라고 알려준다.

Vary: Origin이 없으면,

  • Origin 없는 요청으로 캐시된 응답
  • Origin 있는 요청에도 그대로 재사용

이런 흐름이 가능하다.

반대로 Vary: Origin이 있으면,

  • Origin 없음 → 별도 캐시
  • Origin 있음 → 다른 캐시 키로 처리

가 가능해져서 CORS 충돌 가능성이 줄어든다.

고정 URL 리소스 대응 정리

방법 인프라 작업 필요 여부 재발 위험 비고
버전 파라미터 추가 보통 없음 낮음 가장 단순하고 빠름
CDN Purge만 수행 있음 있음 일회성 대응
Purge + Vary: Origin 있음 낮음 장기적으로 가장 안정적

실무에서는 URL을 제어할 수 있으면 버전 파라미터 추가가 제일 빠르고 확실한 편이다.

반대로 URL을 바꾸기 어렵다면, 인프라 쪽에서 purge와 Vary: Origin까지 함께 봐야 재발을 줄일 수 있다.


외부 CDN 고정 URL이면 배포 순서도 중요하다

사내 정적 자원이 아니라 고정 URL로 쓰는 외부 리소스라면 더 조심해야 한다.

특히 원래는 crossorigin 없이 쓰던 리소스에 이번 배포에서 새로 crossorigin="anonymous"를 붙이는 경우라면, 순서를 잘못 잡으면 기존 사용자에게 바로 CORS 에러를 줄 수 있다.

안전한 순서는 이렇다.

  1. CDN/인프라에서 해당 리소스의 CORS 응답 설정 확인
  2. 필요하면 Vary: Origin 반영
  3. 기존 캐시 purge
  4. 그다음 프론트 코드에서 crossorigin="anonymous" 반영

즉, 프론트 코드만 먼저 바꾸는 게 아니라 캐시와 응답 정책을 먼저 맞춰 놓고 배포하는 쪽이 안전하다.


preconnect는 또 뭐가 다르냐

preconnect는 본질적으로 CORS 에러를 만들어 내는 주범은 아니다.

다만 여기서도 crossorigin을 실제 요청과 맞춰 주지 않으면 미리 열어 둔 연결을 기대만큼 재활용하지 못할 수 있다.

예를 들면 이런 식이다.

<!-- 안 좋은 예 -->
<link rel="preconnect" href="https://cdn.example.com">
<link
  rel="stylesheet"
  href="https://cdn.example.com/common.css"
  crossorigin="anonymous"
/>

이 경우 preconnect는 해 놨는데 실제 요청은 CORS 연결 기준이라 연결 재사용 이점이 줄어들 수 있다.

그래서 아래처럼 맞추는 편이 낫다.

<link rel="preconnect" href="https://cdn.example.com" crossorigin="anonymous">
<link
  rel="stylesheet"
  href="https://cdn.example.com/common.css"
  crossorigin="anonymous"
/>

 


체크리스트

나중에 비슷한 이슈를 다시 만났을 때 빠르게 확인하려면 이 정도는 같이 보면 좋다.

□ 같은 URL을 여러 레이아웃/페이지에서 로드하고 있지 않은가?

□ 그 경우 crossorigin 유무가 전부 동일한가?

□ preload와 실제 stylesheet/script/font 태그의 crossorigin이 일치하는가?

□ noscript fallback에도 같은 정책이 반영돼 있는가?

□ preconnect의 crossorigin이 실제 요청과 맞는가?

□ 외부 CDN 고정 URL에 crossorigin을 새로 붙이는 배포라면
  CDN CORS 설정 / Vary: Origin / cache purge 순서를 먼저 맞췄는가?

정리

이번 이슈를 한 줄로 줄이면 이렇다.

같은 리소스 URL을 페이지마다 서로 다른 CORS 방식으로 요청하면,
브라우저 캐시와 CDN 캐시가 엮이면서 페이지 이동 시에만 간헐적인 CORS 에러가 터질 수 있다.

 

그리고 여기서 실무적으로 기억할 건 두 가지다.

첫째, 같은 URL은 어디서든 같은 crossorigin 정책으로 로드하자.

둘째, 이미 캐시가 퍼져 있는 상태에서 수정 배포할 땐 버전 파라미터, CDN purge, 응답 헤더 설정까지 같이 봐야 한다.

처음엔 “왜 어떤 때만 터지지?” 싶었던 이슈였는데, 결국 뜯어보면 브라우저가 이상한 게 아니라 내가 같은 파일을 서로 다른 방식으로 불러오고 있었던 거였다.

이런 류의 CORS 이슈는 에러 메시지보다 이전 요청 경로와 캐시 상태를 봐야 훨씬 빨리 잡힌다.


참고

  • [HTML Living Standard — CORS settings attributes](https://html.spec.whatwg.org/multipage/urls-and-fetching.html#cors-settings-attributes)
  • [MDN — The crossorigin attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin)
  • [Fetch Living Standard — Request mode](https://fetch.spec.whatwg.org/#concept-request-mode)
  • [MDN — rel="preload" > CORS-enabled fetches](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload#cors-enabled_fetches)
  • [RFC 9111 — HTTP Caching, Section 4.1 (Vary)](https://www.rfc-editor.org/rfc/rfc9111#section-4.1)
  • [MDN — rel="preconnect"](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preconnect)
  • [MDN — HTTP caching > Cache busting](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Caching#cache_busting)

저작자표시 비영리 변경금지 (새창열림)

'FrontEnd > web' 카테고리의 다른 글

브라우저 리소스 요청 과 캐싱 프로세스 흐름  (0) 2026.03.10
[실무 기록] 렌더링 차단(Render‑blocking) 줄이려고 preconnect / preload를 썼는데… 진짜 뭐가 좋아지나?  (0) 2026.03.06
[실무 기록] (2탄) macOS에서 adb가 "개발자 신원을 확인할 수 없습니다"로 막혀 Chrome Inspect가 또 안 될 때  (0) 2026.03.05
[실무 기록] <link rel="stylesheet">로 CSS 불러오는데 간헐적으로 CORS 에러가 나던 이유 (해결: crossorigin 제거)  (1) 2026.01.13
[실무 기록] Chrome Inspect에서 Pending authentication만 뜨고 안드로이드 디버깅이 안 될 때  (0) 2026.01.12
'FrontEnd/web' 카테고리의 다른 글
  • 브라우저 리소스 요청 과 캐싱 프로세스 흐름
  • [실무 기록] 렌더링 차단(Render‑blocking) 줄이려고 preconnect / preload를 썼는데… 진짜 뭐가 좋아지나?
  • [실무 기록] (2탄) macOS에서 adb가 "개발자 신원을 확인할 수 없습니다"로 막혀 Chrome Inspect가 또 안 될 때
  • [실무 기록] <link rel="stylesheet">로 CSS 불러오는데 간헐적으로 CORS 에러가 나던 이유 (해결: crossorigin 제거)
프론트엔드 개발자 jbeat
프론트엔드 개발자 jbeat
프론트엔드 개발자 블로그인데 일상도 쪼그으믐
  • 프론트엔드 개발자 jbeat
    jbeat 님의 블로그
    프론트엔드 개발자 jbeat
  • 전체
    오늘
    어제
    • 분류 전체보기 (44)
      • FrontEnd (43)
        • TypeScript (6)
        • JavaScript (18)
        • Next.js (3)
        • React (1)
        • Testing (2)
        • Third Party (1)
        • web (10)
        • Tooling (1)
        • coding test (0)
        • A.I (1)
      • 일상 (1)
        • wedding (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • 태그

    WebSocket
    Android
    고차함수
    코테
    이터러블
    pick
    Utility
    컬렉션
    Next.js
    배열
    yjs
    CRDT
    TypeScript
    omit
    preconnect
    CrossOrigin
    javascript
    주니어
    playwright
    타입스크립트
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
프론트엔드 개발자 jbeat
[실무 기록] 브라우저 캐시와 CORS 에러
상단으로

티스토리툴바