Spring Framework를 사용하여 OPTIONS 요청에 대한 CORS 사용
서비스에 PUT Ajax를 호출할 때마다 다음 오류가 반환됩니다.
XMLHttpRequest는 http://localhost:8080/users/edit를 로드할 수 없습니다.비행 전 요청에 대한 응답이 액세스 제어 검사를 통과하지 못했습니다.요청한 리소스에 'Access-Control-Allow-Origin' 헤더가 없습니다.따라서 오리진 'http://localhost:63342'에 액세스할 수 없습니다.응답에 HTTP 상태 코드 403이 있습니다.
이틀간의 조사 끝에 코드에 대한 다음 해결책을 시도해 보기로 했습니다.
필요한 클래스를 로드하고 응용 프로그램을 실행하는 기본 클래스입니다.
@SpringBootApplication
@EnableAutoConfiguration
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DispatcherServletInitializer.class, OptionsController.class,Application.class);
}
}
DispatcherServilet Initializer(dispatcherServilet 이니셜라이저). 여기서 dispatch 옵션 요청을 활성화합니다.
public abstract class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setInitParameter("dispatchOptionsRequest", "true");
super.customizeRegistration(registration);
}
}
모든 OPTIONS 요청을 처리하는 컨트롤러:
@Controller
public class OptionsController {
@RequestMapping(method = RequestMethod.OPTIONS)
public HttpServletResponse handle(HttpServletResponse theHttpServletResponse) throws IOException {
theHttpServletResponse.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
theHttpServletResponse.addHeader("Access-Control-Max-Age", "60");
theHttpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
theHttpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
return theHttpServletResponse;
}
}
구성에 문제가 있습니까?
마지막으로 Dispatch Servlet 커스터마이즈 이니셜라이저는 제 문제를 진정으로 해결해 준 수업이었습니다.구현한 옵션 컨트롤러 때문에 OPTIONS 요청이 실패했습니다. 잘못된 것입니다.
그래서 저는 그 옵션 컨트롤러를 제거했고 OPTIONS 요청에 대한 Rest Controller의 핸들 방법을 추가하는 것만으로 문제가 해결되었습니다.
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/users")
public class Users {
@RequestMapping(
value = "/edit",
method = RequestMethod.PUT)
public ResponseEntity<?> create(@RequestBody User user){
....
....
}
@RequestMapping(
value = "/**",
method = RequestMethod.OPTIONS
)
public ResponseEntity handle() {
return new ResponseEntity(HttpStatus.OK);
}
}
최신 버전의 Spring(4.2)을 사용하면 @CrossOrigin의 이점을 누릴 수 있습니다.실제로 Spring < 4.2v를 사용하는 경우 아래와 같이 서블릿 필터를 생성하고 CORS 지원을 위한 헤더를 입력할 수 있습니다.
package it.valeriovaudi.web.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
Copyright 2015 Valerio Vaudi
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
public class CORSFilter implements Filter {
public static final String ACCESS_CONTROL_ALLOW_ORIGIN_NAME = "Access-Control-Allow-Origin";
public static final String DEFAULT_ACCESS_CONTROL_ALLOW_ORIGIN_VALUE = "*";
public static final String ACCESS_CONTROL_ALLOW_METHDOS_NAME = "Access-Control-Allow-Methods";
public static final String DEFAULT_ACCESS_CONTROL_ALLOW_METHDOS_VALUE = "POST, GET, OPTIONS, DELETE";
public static final String ACCESS_CONTROL_MAX_AGE_NAME = "Access-Control-Max-Age";
public static final String DEFAULT_ACCESS_CONTROL_MAX_AGE_VALUE = "3600";
public static final String ACCESS_CONTROL_ALLOW_HEADERS_NAME = "Access-Control-Allow-Headers";
public static final String DEFAULT_ACCESS_CONTROL_ALLOW_HEADERS_VALUE = "x-requested-with";
private String accessControlAllowOrigin = DEFAULT_ACCESS_CONTROL_ALLOW_ORIGIN_VALUE;
private String accessControlAllowMethods = DEFAULT_ACCESS_CONTROL_ALLOW_METHDOS_VALUE;
private String accessControlAllowMaxAge = DEFAULT_ACCESS_CONTROL_MAX_AGE_VALUE;
private String accessControlAllowHeaders = DEFAULT_ACCESS_CONTROL_ALLOW_HEADERS_VALUE;
/**
* @return the method return a map that associated the name of paramiters in the web.xml to the class variable name for the header binding*/
private Map<String,String> initConfig(){
Map<String, String> result = new HashMap<>();
result.put(ACCESS_CONTROL_ALLOW_ORIGIN_NAME,"accessControlAllowOrigin");
result.put(ACCESS_CONTROL_ALLOW_METHDOS_NAME,"accessControlAllowMethods");
result.put(ACCESS_CONTROL_MAX_AGE_NAME,"accessControlAllowMaxAge");
result.put(ACCESS_CONTROL_ALLOW_HEADERS_NAME,"accessControlAllowHeaders");
return result;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String initParameterValue;
Map<String, String> stringStringMap = initConfig();
for (Map.Entry<String, String> stringStringEntry : stringStringMap.entrySet()) {
initParameterValue = filterConfig.getInitParameter(stringStringEntry.getKey());
// if the init paramiter value isn't null then set the value in the correct http header
if(initParameterValue!=null){
try {
getClass().getDeclaredField(stringStringEntry.getValue()).set(this, initParameterValue);
} catch (IllegalAccessException | NoSuchFieldException ignored) { }
}
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader(ACCESS_CONTROL_ALLOW_ORIGIN_NAME, accessControlAllowOrigin);
response.setHeader(ACCESS_CONTROL_ALLOW_METHDOS_NAME, accessControlAllowMethods);
response.setHeader(ACCESS_CONTROL_MAX_AGE_NAME, accessControlAllowMaxAge);
response.setHeader(ACCESS_CONTROL_ALLOW_HEADERS_NAME, accessControlAllowHeaders);
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
Spring boot에서 당신은 이 필터를 Spring bean으로 등록할 수 있고 Spring이 당신을 위해 필터를 등록할 것입니다.
이것이 당신에게 도움이 되기를 바랍니다.
언급URL : https://stackoverflow.com/questions/37733501/enable-cors-for-options-request-using-spring-framework
'codememo' 카테고리의 다른 글
| mysql/messagadbrict_trans_table 모드입니다.활성화하기 전에 로그 (0) | 2023.08.16 |
|---|---|
| Swift의 UIAlert Controller에 TextField를 추가하는 방법 (0) | 2023.08.16 |
| "SqlParameterCollection은 Null이 아닌 SqlParameter 유형 개체만 허용하고 String 개체는 허용하지 않습니다." (0) | 2023.08.16 |
| ORA-29283: "SYS"에서 잘못된 파일 작업 ORA-06512:.UTL_FILE", 536행 (0) | 2023.08.16 |
| 도커는 lxc-tools(사용자 공간 LXC 도구)에 무엇을 추가합니까? (0) | 2023.08.16 |