https://developer.mozilla.org/ko/docs/Web/HTTP/CORS
https://developer.mozilla.org/ko/docs/Glossary/Preflight_request
Access to XMLHttpRequest at ‘http://domain:8080/orders/17’ from origin ‘http://localhost:3000’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
한 문장으로 요약하면, 단순 요청(Simple request)이 아니라면 사전 요청(PreFlight)로 CORS 할 수 있는지 확인한다. 이 때 사전요청 또한 interceptor를 거치게 되는데 사전요청은 interceptor를 통과 할 때 필요로 하는 resource(나의 경우는 header)가 없었다. 그래서 프론트에는 CORS 에러를 받게 되는 것이었다.
이 문제를 아주 쉽게 해결하는 방법은 interceptor의 로직에서 사전요청은 통과시키는 방법이다.
여러 상황이 많다면 더 디테일한 조건이 필요하겠지만, 나는 HTTP method만을 확인해서 통과시키도록 구현했다.
사전 요청은 OPTIONS 메서드이다. 그래서 method가 OPTIONS라면 통과시킨다.
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
if(HttpMethod.OPTIONS.matches(request.getMethod())) {
return true;
}
...
Access-Control-Request-Method
,Access-Control-Request-Headers
, Origin
이렇게 총 3가지의 HTTP request headers를 사용하고, OPTIONS
method를 사용한다.Simple Request
(단순 요청)의 경우에는 생략된다.HTTP/1.1 204 No Content
Connection: keep-alive
Access-Control-Allow-Origin: https://foo.bar.org
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Max-Age: 86400
GET
, POST
, HEAD
만 가능하다.Accept
, Accept-Language
, Content-Language
, Content-Type
만을 허용한다.Content-Type
은 application/x-www-form-urlencoded
, multipart/form-data
, text/plain
만 허용한다.https://fetch.spec.whatwg.org/#cors-safelisted-request-header