CORS Error(next.js+vercel)
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;