[React] CORS(Cross-Origin Resource Sharing) 에러 해결
client와 server가 통신을 할 때 다음과 같은 CORS에러가 발생하는 경우가 있다.
먼저 CORS란?
CORS(Cross-Origin Resource Sharing)는 웹 브라우저가 다른 출처의 자원에 접근하는 것을 제어하는 보안 메커니즘.
기본적으로 웹 브라우저는 동일 출처 정책(Same-Origin Policy)를 적용하기 때문에,
다른 도메인, 프로토콜 또는 포트에서 제공되는 자원에 접근하지 못하도록 제한함.
예를들어 클라이언트의 도메인이 localhost:3000이고
서버의 도메인이 localhost:8000이라고 가정했을때 두 도메인이 다르기 때문에
클라이언트는 localhost:8000에서 받아온 데이터를 제한하는 것임.
주로 발생하는 지점
1. 클라이언트에서 서버로 api요청을 보낼 때, 서버가 올바른 CORS 헤더를 포함하지 않을때
2. 클라이언트가 서버로 보낼 수 없는 HTTP 메서드를 사용할 때
3. 서버가 클라이언트의 요청 헤더를 허용하지 않을 때 발생함.
CORS 문제를 해결하려면 서버와 클라이언트에서 적절한 설정을 해주어야함.
1. 서버 측 설정
서버는 클라이언트의 CORS의 요청을 허용하기 위해
'Access-Control-Allow-Origin' 헤더를 포함해야 함.
이 헤더는 클라이언트의 요청을 허용할 출처를 명시함.
- 모든 출처 허용
Access-Control-Allow-Origin: *
- 특정 출처 허용
Access-Control-Allow-Origin: http://example.com
또한 서버에서 CORS를 설정할 때, 추가적으로 다음과 같은 헤더를 설정할 수 있음.
Access-Control-Allow-Methods: GET, PUT, POST
-> 허용할 HTTP 메서드를 지정
Access-Control-Allow-Headers: 허용할 요청 헤더 지정
등..
2. 클라이언트 측 설정
2-1. 프록시 서버 사용
-> 프록시 서버를 설정하여 클라이언트 요청을 서버로 전달 가능.
(Vite, Webpack 등의 개발 서버에서는 프록시 설정 지원함)
나의 상황은
클라이언트가 서버로 요청을 보내면 서버는 파일에 대한 경로를(100개이상) 응답으로 반환함.
클라이언트 측에서는 이 경로를 사용하여 파일을 읽으려고 시도하는데,
이때 파일 경로의 출처(origin)가 클라이언트의 출처와 다르기 때문에 에러가 발생했다.
Error: Access to fetch at 'path' from origin 'path' han been blocked by CORS policy : No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opague response servers your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
서버에는 이미 CORS 설정이 되어 있지만,
클라이언트는 경로를 가지고 직접 파일을 요청하기 때문에
response.setHeader를 사용하여 파일 응답에 CORS 헤더를 설정할 수 없었음.
request header를 보면 이렇게 cors로 설정된 부분을
no-cors로 변경하는 것도 고려했지만,
이는 cors 정책을 사용하지 않는 것을 의미하기 때문에 자원 접근에 제한이 있고,
근본적인 해결책은 아니라고 생각했음.
그래서 프론트엔드에서 프록시 설정을 시도해보았다.
프록시 설정을 통해 브라우저에서 요청을 보내면, 프록시 서버가 요청을 받아 백엔드 서버로 요청을 보냄.
백엔드 서버로부터 응답을 받은 프록시 서버는 이 응답을 다시 브라우저로 전달함.
이 경우 브라우저는 프록시 서버가 응답한 것으로 인식하므로,
브라우저와 프록시 서버 간의 통신은 동일출처로 간주되는것 !
결과적으로 cors 문제를 우회할 수 있다.
<적용하기>
vite를 사용중이기 때문에 vite.config.js 파일에 프록시 설정을 함.
vite.config.js 파일
export default defineConfig({
plugins: [
react(})
],
server: {
proxy: {
'/api': {
target: 'http://localhost:3001', // 실제 API 서버의 URL
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''), // 프록시 요청 경로 수정
},
},
},
});
/api로 들어오는 모든 요청을 target url로 보냄.
'기타 > 문제해결' 카테고리의 다른 글
[Prometheus] Prometheus 컨테이너 에러 err="open /data/queries.active: permission denied" 해결 (0) | 2024.09.01 |
---|---|
[k3s] coreDNS 중지 오류 (0) | 2024.08.27 |
Window에서 postman 완전 삭제후 재설치 (0) | 2024.08.06 |
oracle vm virtualBox 설치시 에러 (0) | 2024.07.24 |
[node.js] mariaDB 연결 시 unknown plugin auth_gssapi_client 에러 (1) | 2024.07.23 |