1. 程式人生 > >復雜跨域之CorsFilter源碼分析

復雜跨域之CorsFilter源碼分析

請求方式 sea web.xml配置 添加 invalid hand conf imp ring

    1.上篇文章講到,當處理復雜請求時,需要在pom文件引入如下依賴,需在web.xml配置一個過濾器org.apache.catalina.filters.CorsFilter,那麽這個過濾器為我們做了哪些工作呢?,下面對源碼進行分析解讀.

<!--支持跨域-->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>7.0.78</version>
<scope>provided</scope>
</dependency>

    2.首先看doFilter中的初始化代碼,即我們可以在web.xml中初始化我們的數據.如果我們沒有設置,默認允許什麽的來源


public void init(FilterConfig filterConfig) throws ServletException {
this.parseAndStore("*", "GET,POST,HEAD,OPTIONS", "Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers", "", "true", "1800", "true");
默認的設置 //參數1: 表示允許所有的請求源 參數2: 表示允許的http請求方式 參數3:表示允許攜帶的請求頭,
if(filterConfig != null) {
String configAllowedOrigins = filterConfig.getInitParameter("cors.allowed.origins");//支持請求的來源
String configAllowedHttpMethods = filterConfig.getInitParameter("cors.allowed.methods");//支持的方法
String configAllowedHttpHeaders = filterConfig.getInitParameter("cors.allowed.headers");//支持的頭信息
String configExposedHeaders = filterConfig.getInitParameter("cors.exposed.headers");
String configSupportsCredentials = filterConfig.getInitParameter("cors.support.credentials");
String configPreflightMaxAge = filterConfig.getInitParameter("cors.preflight.maxage");
String configDecorateRequest = filterConfig.getInitParameter("cors.request.decorate");
this.parseAndStore(configAllowedOrigins, configAllowedHttpMethods, configAllowedHttpHeaders, configExposedHeaders, configSupportsCredentials, configPreflightMaxAge, configDecorateRequest);
}

}
 

3.doFilter方法,可以看出標紅部分是判斷請求的類型的關鍵,根據不同的訪問類型,將做不同的處理方式,checkRequestType(request)方法根據請求所攜帶的信息判斷訪問的類型是那種,返回的結果有1:NOT_CORS不是跨域請求 2.INVALID_CORS無效的跨域 3.ACTUAL 4.SIMPLE,5.PRE_FLIGHT預請求類型

a.當處理SIMPLE和ACTUAL請求時,調用handleSimpleCORS()方法,此方法會根據用戶設置或者默認設置添加head信息如默認情況("Access-Control-Allow-Origin", "*");即允許所有的跨域源,添加完頭信息,放行進入下個過濾器.

  b.當處理PRE_FLIGHT請求時,調用handlePreflightCORS()方法,添加頭部信息,放回瀏覽器

  c.當處理NOT_CORS請求時,直接放行

  d.當處理INVALID_CORS請求時,response.setStatus(403);返回瀏覽器

  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if(servletRequest instanceof HttpServletRequest && servletResponse instanceof HttpServletResponse) {
            HttpServletRequest request = (HttpServletRequest)servletRequest;
            HttpServletResponse response = (HttpServletResponse)servletResponse;
            CorsFilter.CORSRequestType requestType = this.checkRequestType(request);//關鍵,判斷訪問的類型
            if(this.decorateRequest) {
                decorateCORSProperties(request, requestType);
            }

            switch(CorsFilter.SyntheticClass_1.$SwitchMap$org$apache$catalina$filters$CorsFilter$CORSRequestType[requestType.ordinal()]) {
            case 1:
                this.handleSimpleCORS(request, response, filterChain);
                break;
            case 2:
                this.handleSimpleCORS(request, response, filterChain);
                break;
            case 3:
                this.handlePreflightCORS(request, response, filterChain);
                break;
            case 4:
                this.handleNonCORS(request, response, filterChain);
                break;
            default:
                this.handleInvalidCORS(request, response, filterChain);
            }

        } else {
            throw new ServletException(sm.getString("corsFilter.onlyHttp"));
        }
    }

復雜跨域之CorsFilter源碼分析