Skip to main content

Next.js 13 + Kakao Map API 시 CORS 문제

문제상황

// pages/_document.tsx
<Script
src={"dapi.kakao.com...apikey=SOMETHING"}
strategy="beforeInteractive"
/>

이렇게 개발하고 있었고, 카카오 api 를 이용하기 위한 개발자 페이지에서 URL을 등록하고 있었다

그런대 CORS에러를 만났다.

응답코드도 200으로 떨어지긴한다.

스크립크 로딩 문제일 수도 있어서 일반 script 태그로 바꿨는데 문제가 해결되었다.

// pages/_document.tsx
<script src={"dapi.kakao.com...apikey=SOMETHING"} type="text/javascript" />

일반 script 태그와 Next.js의 스크립트 태그의 차이가 뭘까

Next.js의 Script 컴포넌트와 일반적인 <script> 태그 사이의 동작 차이로 인해 CORS 에러가 발생할 수 있습니다. 이러한 문제의 주요 원인은 다음과 같습니다

  1. 로딩 전략의 차이:
    • Script 컴포넌트는 기본적으로 strategy="beforeInteractive"를 사용하여 스크립트를 로드합니다. 이는 Next.js 애플리케이션의 JavaScript 번들이 로드되기 전에 외부 스크립트를 로드하려고 시도합니다. 이로 인해 일부 외부 스크립트에서는 예상치 못한 동작이나 에러가 발생할 수 있습니다.
    • 반면, 일반적인 <script> 태그는 문서의 파싱과 동시에 스크립트를 로드하고 실행합니다.
  2. 스크립트의 실행 위치:
    • Script 컴포넌트는 React 컴포넌트의 라이프사이클 내에서 동작하므로, 스크립트의 로딩과 실행이 예상한 위치에서 발생하지 않을 수 있습니다.
    • <script> 태그는 HTML 문서 내에서 명시적으로 위치가 정해져 있으므로, 스크립트의 로딩과 실행 위치가 명확합니다.
  3. CORS 정책:
    • 일부 외부 스크립트는 동적으로 생성된 스크립트 태그에 대해 CORS 정책을 적용할 수 있습니다. Script 컴포넌트는 내부적으로 동적으로 스크립트 태그를 생성하므로, 이로 인해 CORS 에러가 발생할 수 있습니다.
    • 반면, <script> 태그는 정적으로 HTML 문서에 포함되므로, 이러한 문제가 발생하지 않을 수 있습니다.

해결 방법

  • Script 컴포넌트의 strategy 속성을 afterInteractive로 설정하여, 애플리케이션의 JavaScript 번들이 로드된 후에 외부 스크립트를 로드하도록 할 수 있습니다.
  • 필요한 경우, <script> 태그를 사용하여 문제를 회피할 수 있습니다.

결론적으로, Next.js의 Script 컴포넌트와 일반적인 <script> 태그 사이의 동작 차이로 인해 일부 외부 스크립트에서는 CORS 에러나 다른 문제가 발생할 수 있습니다. 따라서, 외부 스크립트를 사용할 때는 해당 스크립트의 동작 방식과 호환성을 고려하여 적절한 방법을 선택하는 것이 중요합니다.


왜 이것 때문에 CORS에러가 발생할 수 있나?

Script 컴포넌트는 내부적으로 동적으로 스크립트 태그를 생성하므로, 이로 인해 CORS 에러가 발생할 수 있습니다.

CORS(Cross-Origin Resource Sharing)는 웹 페이지의 요청된 출처와 자원의 출처가 다를 때, 해당 자원에 대한 접근 권한을 브라우저에게 알려주는 보안 표준입니다. 웹 페이지는 기본적으로 동일 출처 정책(Same-Origin Policy)을 따르기 때문에, 다른 출처의 자원을 요청할 때는 해당 자원의 서버가 CORS 헤더를 포함해야 합니다.

Next.js의 Script 컴포넌트가 동적으로 스크립트 태그를 생성할 때 CORS 에러가 발생하는 주요 이유는 다음과 같습니다:

  1. 동적 생성된 스크립트 태그: Script 컴포넌트는 React의 렌더링 과정 중에 스크립트 태그를 동적으로 DOM에 추가합니다. 이 동적으로 생성된 스크립트 태그는 기존의 HTML 문서에 정적으로 포함된 <script> 태그와는 다르게 동작할 수 있습니다.
  2. 추가적인 요청: 동적으로 생성된 스크립트는 추가적인 네트워크 요청을 통해 자원을 가져옵니다. 이 때, 해당 자원의 서버가 CORS 헤더를 제공하지 않거나, 요청한 출처를 허용하지 않는 경우 CORS 에러가 발생할 수 있습니다.
  3. 브라우저의 보안 정책: 브라우저는 사용자의 보안을 위해 동일 출처 정책을 적용합니다. 따라서, 다른 출처의 자원을 요청할 때는 해당 자원의 서버에서 적절한 CORS 헤더를 제공해야 합니다. 동적으로 생성된 스크립트 태그가 이러한 헤더 없이 다른 출처의 자원을 요청하면, 브라우저는 이를 차단하고 CORS 에러를 발생시킵니다.

따라서, Script 컴포넌트를 사용하여 외부 스크립트를 로드할 때 CORS 에러가 발생한다면, 해당 스크립트의 서버 설정을 확인하거나, 필요한 경우 정적 <script> 태그를 사용하여 문제를 회피할 수 있습니다.