自定義WebMvcConfigurer實現CORS配置--原理分析

基於自定義WebMvcConfigurer實現CORS配置–原理分析

原理分析

說明

​ If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. ->摘要自spring boot reference guide

通過spring官方說明明白可以通過WebMvcConfigurer實現額外的MVC配置。

代碼實現

@Configuration
public class ExampleConfig implements WebMvcConfigurer
{  
    @Override
    public void addCorsMappings(CorsRegistry registry)
    {
        // 設置允許跨域的路徑
        registry.addMapping("/**")
                // 設置允許跨域請求的域名
                .allowedOrigins("*")
                // 是否允許證書
                .allowCredentials(true)
                // 設置允許的方法
                .allowedMethods("GET", "POST", "DELETE", "PUT")
                // 設置允許的header屬性
                .allowedHeaders("*")
                // 跨域允許時間
                .maxAge(3600);
    }
}

步驟分析

​ spring初始化時加載corsMapping的配置信息並註冊到實現於IOC容器,具體實例以及信息封裝:RequestMappingHandlerMapping -> corsConfigurationSource -> corsConfigurations

​ 接口訪問時,在DispatchServlet中doDispatch方法裏,通過getHandler拿到HandlerExecutionChain,cors配置信息封裝在HandlerExecutionChain實例中,在getHandler方法中的this.handlerMappings集合中可以看到之前註冊的RequestMappingHandlerMapping。這裏需要注意,請求訪問的header頭中需要包含Origin,因爲在getHandler時會判斷header中是否存在Origin,然後才包裝cors配置信息。具體代碼如下:

if (CorsUtils.isCorsRequest(request)) {
                CorsConfiguration globalConfig = this.corsConfigurationSource.getCorsConfiguration(request);
                CorsConfiguration handlerConfig = this.getCorsConfiguration(handler, request);
                CorsConfiguration config = globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig;
                executionChain = this.getCorsHandlerExecutionChain(request, executionChain, config);
  }

接着回到通過getHandler得到的mappedHandler對象處,往下可以看到執行了mappedHandler.applyPreHandle(processedRequest, response),而我們的cors配置封裝在HandlerInterceptor數組中,這裏通過調用interceptor的preHandle,通過調用鏈:CorsInterceptor.preHandle ->DefaultCorsProcessor.processRequest ->DefaultCorsProcessor.handleInternal 在這裏將配置的cors信息寫入response的header中完成跨域信息響應注入。

這塊其實spring官方也有給出解釋(摘要自CORS support in Spring Framework):

How does it work?

CORS requests (including preflight ones with an OPTIONS method) are automatically dispatched to the various HandlerMappings registered. They handle CORS preflight requests and intercept CORS simple and actual requests thanks to a CorsProcessor implementation (DefaultCorsProcessor by default) in order to add the relevant CORS response headers (like Access-Control-Allow-Origin). CorsConfiguration allows you to specify how the CORS requests should be processed: allowed origins, headers, methods, etc. It can be provided in various ways:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章