today,weekly I learn

CORS Error(next.js+vercel)

rhdaud2 2024. 7. 5. 13:01

Access to XMLHttpRequest at '주소A' from origin '주소B' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

 

 

동일 출처 정책 (same-origin policy/ sop)

- 다른 origin 에서 요청한 것을 기본적으로 제한하여 위험을 방지하는 것

 

origin : url의  scheme, host, port-number 3가지로 판단

 

 

 교차 출처 리소스 공유( Cross-Origin Resource Sharing, CORS)

- same origin policy가 안전을 보장해주지만, 의도적으로 다른 리소스와 상호작용을 원할 경우 제한적인데

이럴 경우 cors를 사용할 수도 있다

 

응답 헤더 파일에 예외 사이트 설정.

 

 

 


 

현 상황

 

기존에 next.js 라우트핸들러를 이용해, localhost:3000/-/- 형식을 버셀 배포 주소로 변경해버려서

cors 에러 발생

(서버 사이드에서 호출하는 request는 서버 호출이라 cors 에러가 발생하지 않는다,

배포시에 아래와 같은 클라이언트 컴포넌트에서 주로 발생)

import { Pokemon } from "@/types/poketmon.type";
import { useQuery } from "@tanstack/react-query";
import axios, { AxiosError } from "axios";

interface Props {
  page: number;
}

export const usePokemonQuery = ({ page }: Props) => {
  const { data: pokemons, isPending: pokemonsIsPending } = useQuery<
    Pokemon[],
    AxiosError,
    Pokemon[]
  >({
    queryKey: ["pokemons", page],
    queryFn: async () => {
      const response = await axios.get(
        `https://pokedex-rouge-theta-13.vercel.app/api/poketmon?page=${page}`
      );

      return response.data;
    },
  });
  return { pokemons, pokemonsIsPending };
};

export default usePokemonQuery;

 

 

axios 라이브러리를 사용중이기에, 현 상황에서는 앞 url을 제거하고 아래와 같이 남기면 문제는 해결된다

      const response = await axios.get(
        `/api/poketmon?page=${page}`
      );

 

 

 

만약 axios 사용중이 아니거나 url 전체를 입력해야하는 상황에는 cors 우회를 해야하는데,

프론트엔드에서 cors 우회의 방법 중 하나는 proxy이고, rewrite로 대체할 수 있다고 한다

 

next.config.js파일에 아래와 같이 작성하면

desrination에 보내는 request 주소를 source 주소에서 요청한 것 처럼 보여지게 rewrite 하는 것 

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  async rewrites() {
    return [
      {
        source: "/:path*",
        destination: "(전달받은 API 주소)/:path*",
      },
    ];
  },
};

module.exports = nextConfig;