Cors跨域拦截实现过程
所有的请求都进入CorsFilter的doFilterInternal方法
org.springframework.web.filter.CorsFilter
//在这里过滤所有请求
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
if (CorsUtils.isCorsRequest(request)) {
CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
if (corsConfiguration != null) {
boolean isValid = this.processor.processRequest(corsConfiguration, request, response);
//这里是(org.springframework.web.cors.DefaultCorsProcessor类方法processRequest)处 理请求是否符合规则
if (!isValid || CorsUtils.isPreFlightRequest(request)) {//fasle时放行请求;true时 拦截return
return;
}
}
}
filterChain.doFilter(request, response);
}
org.springframework.web.cors.DefaultCorsProcessor
@Override
@SuppressWarnings("resource")
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);
}
/**
* Handle the given request.
*/
protected boolean handleInternal(ServerHttpRequest request, ServerHttpResponse response,
CorsConfiguration config, boolean preFlightRequest) throws IOException {
String requestOrigin = request.getHeaders().getOrigin();
String allowOrigin = checkOrigin(config, requestOrigin);
HttpMethod requestMethod = getMethodToUse(request, preFlightRequest);
List<HttpMethod> allowMethods = checkMethods(config, requestMethod);
List<String> requestHeaders = getHeadersToUse(request, preFlightRequest);
List<String> allowHeaders = checkHeaders(config, requestHeaders);
if (allowOrigin == null || allowMethods == null || (preFlightRequest && allowHeaders == null)) {
//这里去判断是否符合配置单规则
rejectRequest(response);
return false;
}
HttpHeaders responseHeaders = response.getHeaders();
responseHeaders.setAccessControlAllowOrigin(allowOrigin);
responseHeaders.add(HttpHeaders.VARY, HttpHeaders.ORIGIN);
if (preFlightRequest) {
responseHeaders.setAccessControlAllowMethods(allowMethods);
}
if (preFlightRequest && !allowHeaders.isEmpty()) {
responseHeaders.setAccessControlAllowHeaders(allowHeaders);
}
if (!CollectionUtils.isEmpty(config.getExposedHeaders())) {
responseHeaders.setAccessControlExposeHeaders(config.getExposedHeaders());
}
if (Boolean.TRUE.equals(config.getAllowCredentials())) {
responseHeaders.setAccessControlAllowCredentials(true);
}
if (preFlightRequest && config.getMaxAge() != null) {
responseHeaders.setAccessControlMaxAge(config.getMaxAge());
}
response.flush();
return true;
}
若有不正之处请指出,谢谢!