1、相关组件

2、cors注册

CorsRegistry:作为cors注册者,管理跨域配置。

CorsRegistration:作为Cors的注册项,包含路径模式及对应的跨域配置

CorsConfigurationSource:作为cors配置的提供者接口

UrlBaseCorsConfigurationSource:是CorsConfigurationSource的一个具体实现

3、Cors处理

4、spring mvc中cors的初始化及运行

4.1 初始化

通过WebMvcConfigurer.addCorsMappings添加自定义跨域配置。因为在DelegatingWebMvcConfiguration配置中初始化时会添加自定义的WebMvcConfigurer放入到WebMvcConfigurerComposite中。

//DelegatingWebMvcConfiguration
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();@Autowired(required = false)public void setConfigurers(List<WebMvcConfigurer> configurers) {if (!CollectionUtils.isEmpty(configurers)) {this.configurers.addWebMvcConfigurers(configurers);}}protected void addCorsMappings(CorsRegistry registry) {this.configurers.addCorsMappings(registry);}

在WebMvcConfigurationSupport中的requestMappingHandlerMapping中获取cors配置,并且设置到RequestMappingHandlerMapping中

public RequestMappingHandlerMapping requestMappingHandlerMapping(@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,@Qualifier("mvcConversionService") FormattingConversionService conversionService,@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();mapping.setOrder(0);mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));mapping.setContentNegotiationManager(contentNegotiationManager);mapping.setCorsConfigurations(getCorsConfigurations());PathMatchConfigurer pathConfig = getPathMatchConfigurer();if (pathConfig.getPatternParser() != null) {mapping.setPatternParser(pathConfig.getPatternParser());}else {mapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault());mapping.setPathMatcher(pathConfig.getPathMatcherOrDefault());Boolean useSuffixPatternMatch = pathConfig.isUseSuffixPatternMatch();if (useSuffixPatternMatch != null) {mapping.setUseSuffixPatternMatch(useSuffixPatternMatch);}Boolean useRegisteredSuffixPatternMatch = pathConfig.isUseRegisteredSuffixPatternMatch();if (useRegisteredSuffixPatternMatch != null) {mapping.setUseRegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch);}}Boolean useTrailingSlashMatch = pathConfig.isUseTrailingSlashMatch();if (useTrailingSlashMatch != null) {mapping.setUseTrailingSlashMatch(useTrailingSlashMatch);}if (pathConfig.getPathPrefixes() != null) {mapping.setPathPrefixes(pathConfig.getPathPrefixes());}return mapping;}protected final Map<String, CorsConfiguration> getCorsConfigurations() {if (this.corsConfigurations == null) {CorsRegistry registry = new CorsRegistry();addCorsMappings(registry);this.corsConfigurations = registry.getCorsConfigurations();}return this.corsConfigurations;}

4.2 运行时

在运行时,在获取HandlerExecutionChain时,会判断是否有跨域配置源,如果有,判断请求是否是preflight请求,则创建包含PreFlightHandler的执行链,否则就在执行链中添加跨域请求拦截器,拦截器通过CrosProcessor处理请求。

public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {Object handler = getHandlerInternal(request);if (handler == null) {handler = getDefaultHandler();}if (handler == null) {return null;}// Bean name or resolved handler?if (handler instanceof String) {String handlerName = (String) handler;handler = obtainApplicationContext().getBean(handlerName);}HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);if (logger.isTraceEnabled()) {logger.trace("Mapped to " + handler);}else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {logger.debug("Mapped to " + executionChain.getHandler());}if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {CorsConfiguration config = getCorsConfiguration(handler, request);if (getCorsConfigurationSource() != null) {CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);config = (globalConfig != null ? globalConfig.combine(config) : config);}if (config != null) {config.validateAllowCredentials();}executionChain = getCorsHandlerExecutionChain(request, executionChain, config);}return executionChain;}protected HandlerExecutionChain getCorsHandlerExecutionChain(HttpServletRequest request,HandlerExecutionChain chain, @Nullable CorsConfiguration config) {if (CorsUtils.isPreFlightRequest(request)) {HandlerInterceptor[] interceptors = chain.getInterceptors();return new HandlerExecutionChain(new PreFlightHandler(config), interceptors);}else {chain.addInterceptor(0, new CorsInterceptor(config));return chain;}}private class PreFlightHandler implements HttpRequestHandler, CorsConfigurationSource {@Nullableprivate final CorsConfiguration config;public PreFlightHandler(@Nullable CorsConfiguration config) {this.config = config;}@Overridepublic void handleRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {corsProcessor.processRequest(this.config, request, response);}@Override@Nullablepublic CorsConfiguration getCorsConfiguration(HttpServletRequest request) {return this.config;}}private class CorsInterceptor implements HandlerInterceptor, CorsConfigurationSource {@Nullableprivate final CorsConfiguration config;public CorsInterceptor(@Nullable CorsConfiguration config) {this.config = config;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {// Consistent with CorsFilter, ignore ASYNC dispatchesWebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);if (asyncManager.hasConcurrentResult()) {return true;}return corsProcessor.processRequest(this.config, request, response);}@Override@Nullablepublic CorsConfiguration getCorsConfiguration(HttpServletRequest request) {return this.config;}}

spring中mvc的跨域访问相关推荐

  1. Spring Boot 对CORS跨域访问的配置

    Springboot 对于跨域请求的支持有两种配置方式: 一:注解配置 @CrossOrigin注解可以实现对CORS的启用. @RequestMapping("/get_api" ...

  2. 在Firefox中通过AJAX跨域访问Web资源

    一.解决在firefox中无法跨域访问的问题 AJAX从本质上讲就是命名用XMLHttpRequest组件来向服务端发送HTTP请求,请接收相应信息.至于成功接收到响应信息后的操作,就和普通的Web客 ...

  3. Spring Boot配置跨域访问策略

    From: https://blog.csdn.net/garyond/article/details/80192760 1. 引言 我们在开发过程中通常因为不同应用之间的接口调用或者应用之间接口集成 ...

  4. yii2 跨域请求配置_如何在SpringBoot应用中实现跨域访问资源和消息通信?

    允许跨域访问 CORS ( Cross Origin Resource Sharing,跨域资源共享)机制允许Web应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行.浏览器支持在API容器中 ...

  5. Java后端带参跨域访问_java后端解决请求跨域

    跨域 跨域:指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制. 例如:a页面想获取b页面资源,如果a.b页面的协议.域名.端口.子域名不同 ...

  6. AJAX跨域访问解决方案

    Case I. Web代理的方式 (on Server A) 即用户访问A网站时所产生的对B网站的跨域访问请求均提交到A网站的指定页面,由该页面代替用户页面完成交互,从而返回合适的结果.此方案可以解决 ...

  7. mui后端开发php,PHP解决mui中ajax的跨域问题

    什么是跨域访问 在A网站中,我们希望使用Ajax来获得B网站中的特定内容.如果A网站与B网站不在同一个域中,那么就出现了跨域访问问题.你可以理解为两个域名之间不能跨过域名来发送请求或者请求数据,否则就 ...

  8. [转]Ajax跨域访问问题-方法大全

    Case I. Web代理的方式 (on Server A) 即用户访问A网站时所产生的对B网站的跨域访问请求均提交到A网站的指定页面,由该页面代替用户页面完成交互,从而返回合适的结果.此方案可以解决 ...

  9. Web应用跨域访问解决方案

    Web应用跨域访问解决方案 Web应用的跨域访问解决方案 Web跨域访问解决方案 做过跨越多个网站的Ajax开发的朋友都知道,如果在A网站中,我们希望使用Ajax来获得B网站中的特定内容,如果A网站与 ...

最新文章

  1. python snmp 交换机 配置文件_如何使用python从SNMP获取数据?
  2. 使用frameset时的target属性
  3. python中str的索引、切片
  4. ubuntu12.04安装lamp的简单lamp
  5. python 组合数据类型_【Python】组合数据类型
  6. mac os系统使用Visual Studio Code打开浏览器查看HTML文件
  7. python中如何调用类_python如何调用java类
  8. boost::mp11::mp_iota相关用法的测试程序
  9. 计算机基础知识表格加密管理,【事业单位考试】计算机网络知识:数据加密技术之密钥管理...
  10. ajax前端实时获取数据
  11. 第三周作业2——效能测试
  12. Ubuntu 9.04安装永中Office 2009
  13. 热血江湖游戏中断开服务器,为什么最近老是一进去游戏就提示与服务器断开 – 手机爱问...
  14. 【Vue】从零搭建一个Vue项目
  15. poj 1321 排兵布阵问题 dfs算法
  16. MySQL之父开发的 MariaDB 数据库,扩展了新功能……
  17. jzoj 3837 心灵终结
  18. 拼多多店铺推广有哪些技巧?
  19. [oh-my-zsh] 提示检测到不安全的完成相关目录的问题解决
  20. 在三星smart TV上开发widget-入门篇 1

热门文章

  1. firedac的TFDStoredProc动态创建并调用存储过程
  2. Last-Modified、If-Modified-Since 实现缓存和 OutputCache 的区别
  3. Codeforces Round #265 (Div. 2) E. Substitutes in Number
  4. FragmentTabHost切换Fragment时避免重复加载UI
  5. 『原创』网站测试计划模板
  6. python快乐编程—基础入门-从萌新到大神必读书籍 《Python快乐编程基础入门》...
  7. python入门到精通需要学多久-史上最详细python学习路线-从入门到精通,只需5个月时间...
  8. python入门指南bl-Python Matplotlib 绘图使用指南 (附代码)
  9. python基础知识资料-Python基础知识汇总
  10. python类型-Python入门之类(class)