目前很多网站应用到HTML5,使用前后端分离的开发方案。前后端分离就会有跨域的问题。本文即对跨域问题的一点探究(除JSONP)。
Spring 4.X提供了 @CrossOrigin 跨域注解
具体设置可以参考 http://spring.io/guides/gs/rest-service-cors/
注意:映射处理器配对: DefaultAnnotationHandlerMapping - AnnotationMethodHandlerAdapter不支持此注解标签
NOTE: Method-level mappings are only allowed to narrow the mapping expressed at the class level (if any). HTTP paths need to uniquely map onto specific handler beans,
with any given HTTP path only allowed to be mapped onto one specific handler bean (not spread across multiple handler beans). It is strongly recommended to co-locate
related handler methods into the same bean.
参考文档: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/mvc/annotation/DefaultAnnotationHandlerMapping.html
如果是基于SpringMVC框架web项目需要做如下配置:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
<!-- support Preflighted requests(用于支持预检options-AbstractHandlerMapping$PreFlightHandler处理) -->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>
有待处理:
使用在拦截器中response增加header方式设置cors的方式,跨域未解决。
追踪代码(入口: DispatcherServlet.doDispatch):
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
PreFlightHandler.handleRequest:
corsProcessor.processRequest(this.config, request, response);
DefaultCorsProcessor.processRequest:
public boolean processRequest(CorsConfiguration config, HttpServletRequest request, HttpServletResponse response)
throws IOException {
if (!CorsUtils.isCorsRequest(request)) {
return true;
}
ServletServerHttpResponse serverResponse = new ServletServerHttpResponse(response);
if (responseHasCors(serverResponse)) {
logger.debug("Skip CORS processing: response already contains \"Access-Control-Allow-Origin\" header");
return true;
}
ServletServerHttpRequest serverRequest = new ServletServerHttpRequest(request);
if (WebUtils.isSameOrigin(serverRequest)) {
logger.debug("Skip CORS processing: request is from same origin");
return true;
}
boolean preFlightRequest = CorsUtils.isPreFlightRequest(request);
if (config == null) {
if (preFlightRequest) {
rejectRequest(serverResponse);
return false;
}
else {
return true;
}
}
return handleInternal(serverRequest, serverResponse, config, preFlightRequest);
}
疑问是在ServletServerHttpResponse serverResponse = new ServletServerHttpResponse(response)之后,
在拦截器中设置的header信息获取不到,希望有朋友可以给我指点下。
Spring 4.X提供了 @CrossOrigin 跨域注解
具体设置可以参考 http://spring.io/guides/gs/rest-service-cors/
注意:映射处理器配对: DefaultAnnotationHandlerMapping - AnnotationMethodHandlerAdapter不支持此注解标签
NOTE: Method-level mappings are only allowed to narrow the mapping expressed at the class level (if any). HTTP paths need to uniquely map onto specific handler beans,
with any given HTTP path only allowed to be mapped onto one specific handler bean (not spread across multiple handler beans). It is strongly recommended to co-locate
related handler methods into the same bean.
参考文档: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/mvc/annotation/DefaultAnnotationHandlerMapping.html
如果是基于SpringMVC框架web项目需要做如下配置:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
<!-- support Preflighted requests(用于支持预检options-AbstractHandlerMapping$PreFlightHandler处理) -->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"></bean>
有待处理:
使用在拦截器中response增加header方式设置cors的方式,跨域未解决。
追踪代码(入口: DispatcherServlet.doDispatch):
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
PreFlightHandler.handleRequest:
corsProcessor.processRequest(this.config, request, response);
DefaultCorsProcessor.processRequest:
public boolean processRequest(CorsConfiguration config, HttpServletRequest request, HttpServletResponse response)
throws IOException {
if (!CorsUtils.isCorsRequest(request)) {
return true;
}
ServletServerHttpResponse serverResponse = new ServletServerHttpResponse(response);
if (responseHasCors(serverResponse)) {
logger.debug("Skip CORS processing: response already contains \"Access-Control-Allow-Origin\" header");
return true;
}
ServletServerHttpRequest serverRequest = new ServletServerHttpRequest(request);
if (WebUtils.isSameOrigin(serverRequest)) {
logger.debug("Skip CORS processing: request is from same origin");
return true;
}
boolean preFlightRequest = CorsUtils.isPreFlightRequest(request);
if (config == null) {
if (preFlightRequest) {
rejectRequest(serverResponse);
return false;
}
else {
return true;
}
}
return handleInternal(serverRequest, serverResponse, config, preFlightRequest);
}
疑问是在ServletServerHttpResponse serverResponse = new ServletServerHttpResponse(response)之后,
在拦截器中设置的header信息获取不到,希望有朋友可以给我指点下。