@Override
public void doFilter(final ServletRequest servletRequest,
final ServletResponse servletResponse, final FilterChain filterChain)
throws IOException, ServletException {
if (!(servletRequest instanceof HttpServletRequest) ||
!(servletResponse instanceof HttpServletResponse)) {
throw new ServletException(sm.getString("corsFilter.onlyHttp"));
}
// Safe to downcast at this point.
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// Determines the CORS request type.
CorsFilter.CORSRequestType requestType = checkRequestType(request);
// Adds CORS specific attributes to request.
if (decorateRequest) {
CorsFilter.decorateCORSProperties(request, requestType);
}
switch (requestType) {
case SIMPLE:
// Handles a Simple CORS request.
this.handleSimpleCORS(request, response, filterChain);
break;
case ACTUAL:
// Handles an Actual CORS request.
this.handleSimpleCORS(request, response, filterChain);
break;
case PRE_FLIGHT:
// Handles a Pre-flight CORS request.
this.handlePreflightCORS(request, response, filterChain);
break;
case NOT_CORS:
// Handles a Normal request that is not a cross-origin request.
this.handleNonCORS(request, response, filterChain);
break;
default:
// Handles a CORS request that violates specification.
this.handleInvalidCORS(request, response, filterChain);
break;
}
}
以上为org.apache.catalina.filters.CorsFilter核心代码,用switch case处理各种情况,其中在处理PRE_FLIGHT(刺探请求,比如跨域中的复杂请求,会先发一个options请求,这个请求就属于PRE_FLIGHT)时,处理完之后,不会再继续后续过滤器链:
/**
* Handles CORS pre-flight request.
*
* @param request
* The {@link HttpServletRequest} object.
* @param response
* The {@link HttpServletResponse} object.
* @param filterChain
* The {@link FilterChain} object.
* @throws IOException
* @throws ServletException
*/
protected void handlePreflightCORS(final HttpServletRequest request,
final HttpServletResponse response, final FilterChain filterChain)
throws IOException, ServletException {
CORSRequestType requestType = checkRequestType(request);
if (requestType != CORSRequestType.PRE_FLIGHT) {
throw new IllegalArgumentException(sm.getString("corsFilter.wrongType1",
CORSRequestType.PRE_FLIGHT.name().toLowerCase(Locale.ENGLISH)));
}
//此处省略了中间代码
...
// Section 6.2.9
response.addHeader(
CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_METHODS,
accessControlRequestMethod);
// Section 6.2.10
if ((allowedHttpHeaders != null) && (!allowedHttpHeaders.isEmpty())) {
response.addHeader(
CorsFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_HEADERS,
join(allowedHttpHeaders, ","));
}
// Do not forward the request down the filter chain.
//到此方法就结束了
}
由于不再走后续过滤器,再和其他过滤器进行整合时,需要注意处理逻辑,必要时请将org.apache.catalina.filters.CorsFilter放置于过滤器末端。
对于PRE_FLIGHT的解释,参考下边源码:
protected static enum CORSRequestType {
/**
* A simple HTTP request, i.e. it shouldn't be pre-flighted.
*/
SIMPLE,
/**
* A HTTP request that needs to be pre-flighted.
*/
ACTUAL,
/**
* A pre-flight CORS request, to get meta information, before a
* non-simple HTTP request is sent.
* 在发送简单请求前,为了获取meta信息而发送的预检请求(刺探)
*/
PRE_FLIGHT,
/**
* Not a CORS request, but a normal request.
*/
NOT_CORS,
/**
* An invalid CORS request, i.e. it qualifies to be a CORS request, but
* fails to be a valid one.
*/
INVALID_CORS
}