![[Nginx] Access to XMLHttpRequest at ‘’ from origin ‘’ has been blocked by CORS policy: Response to preflight allowed for a preflight requet 해결](https://image.inblog.dev?url=https%3A%2F%2Finblog.ai%2Fapi%2Fog%3Ftitle%3D%255BNginx%255D%2520Access%2520to%2520XMLHttpRequest%2520at%2520%25E2%2580%2598%25E2%2580%2599%2520from%2520origin%2520%25E2%2580%2598%25E2%2580%2599%2520has%2520been%2520blocked%2520by%2520CORS%2520policy%253A%2520Response%2520to%2520preflight%2520allowed%2520for%2520a%2520preflight%2520requet%2520%25ED%2595%25B4%25EA%25B2%25B0%26logoUrl%3Dhttps%253A%252F%252Finblog.ai%252Finblog_logo.png%26blogTitle%3Dsilver0-stack&w=2048&q=75)

Access to XMLHttpRequest at ‘백엔드 도메인’ from origin ‘프론트 도메인’ has been blocked by CORS policy: Response to preflight allowed for a preflight requet
GET https://api.~~~net::ERR_FAILED
Axios Error: Network Error
정말 정말 며칠동안 붙잡고 있던 오류였다. 그냥 흔한 axios 통신할 때 프론트엔드에서 백엔드에 접근을 하지 못하는 CORS 정책 문제였다. 이미 스프링부트의 WebConfig 파일에 이렇게 CORS 설정을 해준 상태였다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("https://mumul.site")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")
.allowedHeaders("*")
.allowCredentials(true) // 쿠키 인증 요청 허용
.exposedHeaders("Authorization")
.exposedHeaders("Access-Control-Allow-Origin")// "Access-Control-Allow-Origin" 헤더를 노출
.maxAge(3000); // 원하는 시간만큼 pre-flight 리퀘스트를 캐싱
}
}
근데 전혀 오류가 사라질 기미가 없었다. 그래서 컨트롤러에
@CrossOrigin(origins = "https://mumul.site")
를 작성해서 리액트 도메인인 https://mumul.site
에서 백엔드 도메인 주소로 크로스 오리진 접근이 가능하도록 시도해 봤다. 그런데도 효과는 없었다.백엔드에서 CORS Filter 메소드도 작성도 해봤지만 CORS 에러는 사라져줄 기미가 보이지 않았다.
그러다 새삼스럽게 알게된 사실, 아 나는 지금 프론트엔드 도메인과 백엔드 도메인이 각각 Nginx를 웹 서버로서 사용하고 있지. 그래서 CORS 설정도 백엔드 nginx conf 파일에서 해주어야 한다는 사실.
Nginx
사용 시4xx
또는5xx
오류에 대해 서버는Access-Control-Allow-Origin
를 응답 헤더에 추가하지 않는다. 서버는2xx
과3xx(redirection)
에 대해서만 해당 헤더를 보낸다.만약4xx
또는5xx
오류에 대해서도Access-Control-Allow-Origin
를 응답 헤더에 추가하고 싶다면Nginx
에서 아래와 같이 추가하면 된다.add_header <header_name> <value> always
# example add_header 'Access-Control-Allow-Origin' '*' always
아~ 그랬구나.
nginx.conf 파일을 열어준다
~$ sudo nano /etc/nginx/nginx.conf
서버 블록 안에 있는 로케이션 블록에 CORS 설정 코드를 넣어준다
if ($http_origin ~* (https://mumul\.site)) {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Origin, X-Requested-With, Content-Type, Accept' al>
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Max-Age' '3000';
add_header 'Access-Control-Expose-Headers' 'Authorization';
}
$http_origin ~* (https://mumul\.site))
요청하는 origin 헤더가 “https://mumul.site” 와 일치하는지 확인하는 조건문이다/ ~* 는 정규 표현식에서 대소문자를 구별하지 않는 매칭을 의미한다
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
클라이언트의 Origin 헤더와 동일한 값(여기선 https://mumul.site)를 ‘Access-Control-Allow-Origin 헤더에 응답으로 추가한다는 것이다. 이러면 해당 출처에서 온 요청은 허용한다.
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH' always;
허용되는 HTTP 메소드이다.
add_header 'Access-Control-Allow-Headers' 'Authorization, Origin, X-Requested-With, Content-Type, Accept' always;
클라이언트에서 서버로 전송할 수 있는 요청 헤더 목록을 지정한 것이다.
add_header 'Access-Control-Allow-Credentials' 'true' always;
클라이언트가 인증된 상태로 요청을 보낼 수 있도록 허용한다. CORS 요청에서 credentials (즉, 쿠키와 HTTP 인증 정보)를 허용할지 여부를 설정한다
add_header 'Access-Control-Max-Age' '3000'
브라우저가 사전 검사 요청(pre-flight)을 캐시할 수 잇는 시간을 설정한 것이다. 사전 검사 요청의 결과를 캐시하려 성능을 향상시킨다.
add_header 'Access-Control-Expose-Headers' 'Authorization';
응답 헤더에 Authorization을 노출시켜서 클라이언트가 접근 가능하도록 한다.
그랬더니 콘솔 창에 CORS 가 사라진다. 내가 지금 뭘 하고 있는지 인지에서 시작하는 한걸음이었다.
Share article