当前位置:

首页 > 编程开发 > Springboot怎么通过配置WebMvcConfig处理Cors非同源访问跨域问题

Springboot怎么通过配置WebMvcConfig处理Cors非同源访问跨域问题

关于Cors跨域的问题,前端有代理和jsonp的常用方式解决这种非同源的访问拒绝策略,什么是同源?即域名一致端口一致但是端口下访问的接口api不同的两种或者几种的互相访问叫做同源访问,但是若是接口不一致或者域名不一致(这里泛指IP不一致),那么对应的就属于非同源访问,浏览器会拒绝发出请求,直接回复404,有时候我也见过恢复202的就是发出去了但是被后端的Mvc处理hander链给拒绝了。那么配置MVC是后端处理Cors问题的一种解决思路。之前学习过MVC的处理链路,从一次请求发过来到回复数据总共11次处理

本文目录

    关于Cors跨域的问题,前端有代理和jsonp的常用方式解决这种非同源的访问拒绝策略,什么是同源?即域名一致端口一致但是端口下访问的接口api不同的两种或者几种的互相访问叫做同源访问,但是若是接口不一致或者域名不一致(这里泛指IP不一致),那么对应的就属于非同源访问,浏览器会拒绝发出请求,直接回复404,有时候我也见过恢复202的就是发出去了但是被后端的Mvc处理hander链给拒绝了。那么配置MVC是后端处理Cors问题的一种解决思路。

    之前学习过MVC的处理链路,从一次请求发过来到回复数据总共11次处理:

    Springboot怎么通过配置WebMvcConfig处理Cors非同源访问跨域问题

    请求发送到服务器端时是由我们的MVC进行处理的,而统一调配任务流程的则是我们的请求分发器,注意这里请求到处理器之后回去寻找处理器适配器(符合校验处理的请求才能被允许例如接口含有的合法api,以及跨域原则),之前我们的微信小程序开发过程中是没有考虑跨域问题的,原因是我们知道小程序的请求处理都是由微信后台进行分发处理的,也就是在微信的后台时就做了前端的跨域处理,大概是采用动态代理的方式解决了小程序的跨域。

    那么我们先看看MVC的配置接口 WebMvcConfigurer 的源代码:

    public interface WebMvcConfigurer {
        default void configurePathMatch(PathMatchConfigurer configurer) {
        }
        default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        }
        default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        }
        default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        }
        default void addFormatters(FormatterRegistry registry) {
        }
        default void addInterceptors(InterceptorRegistry registry) {
        }
        default void addResourceHandlers(ResourceHandlerRegistry registry) {
        }
        default void addCorsMappings(CorsRegistry registry) {
        }
        default void addViewControllers(ViewControllerRegistry registry) {
        }
        default void configureViewResolvers(ViewResolverRegistry registry) {
        }
        default void addArgumentResolvers(List resolvers) {
        }
        default void addReturnValueHandlers(List handlers) {
        }
        default void configureMessageConverters(List> converters) {
        }
        default void extendMessageConverters(List> converters) {
        }
        default void configureHandlerExceptionResolvers(List resolvers) {
        }
        default void extendHandlerExceptionResolvers(List resolvers) {
        }
        @Nullable
        default Validator getValidator() {
            return null;
        }
        @Nullable
        default MessageCodesResolver getMessageCodesResolver() {
            return null;
        }
    }

    它的内部是具备一些处理器解析器以及映射的添加与配置的方法的,那么我们要解决Cros跨域问题就是要考虑addCorsMappings 配置Cros映射,所以我们点进去看看这注册Cros的 CorsRegistry 的源码:

    public class CorsRegistry {
        private final List registrations = new ArrayList();
        public CorsRegistry() {
        }
        public CorsRegistration addMapping(String pathPattern) {
            CorsRegistration registration = new CorsRegistration(pathPattern);
            this.registrations.add(registration);
            return registration;
        }
        protected Map getCorsConfigurations() {
            Map configs = CollectionUtils.newLinkedHashMap(this.registrations.size());
            Iterator var2 = this.registrations.iterator();
            while(var2.hasNext()) {
                CorsRegistration registration = (CorsRegistration)var2.next();
                configs.put(registration.getPathPattern(), registration.getCorsConfiguration());
            }
            return configs;
        }
    }

    从上述代码中不难发现,内部有一个不可改变的 CorsRegistration 数组链表,以及增加映射的方法,主要还是看看它具备的元素 CorsRegistration 含有什么配置项:

    public class CorsRegistration {
        private final String pathPattern;
        private CorsConfiguration config;
        public CorsRegistration(String pathPattern) {
            this.pathPattern = pathPattern;
            this.config = (new CorsConfiguration()).applyPermitDefaultValues();
        }
        public CorsRegistration allowedOrigins(String... origins) {
            this.config.setAllowedOrigins(Arrays.asList(origins));
            return this;
        }
        public CorsRegistration allowedOriginPatterns(String... patterns) {
            this.config.setAllowedOriginPatterns(Arrays.asList(patterns));
            return this;
        }
        public CorsRegistration allowedMethods(String... methods) {
            this.config.setAllowedMethods(Arrays.asList(methods));
            return this;
        }
        public CorsRegistration allowedHeaders(String... headers) {
            this.config.setAllowedHeaders(Arrays.asList(headers));
            return this;
        }
        public CorsRegistration exposedHeaders(String... headers) {
            this.config.setExposedHeaders(Arrays.asList(headers));
            return this;
        }
        public CorsRegistration allowCredentials(boolean allowCredentials) {
            this.config.setAllowCredentials(allowCredentials);
            return this;
        }
        public CorsRegistration maxAge(long maxAge) {
            this.config.setMaxAge(maxAge);
            return this;
        }
        public CorsRegistration combine(CorsConfiguration other) {
            this.config = this.config.combine(other);
            return this;
        }
        protected String getPathPattern() {
            return this.pathPattern;
        }
        protected CorsConfiguration getCorsConfiguration() {
            return this.config;
        }
    }

    我们可以发现内部是具备允许放行:请求头,请求路径,请求方法,请求源策略的方法的,所以我们在这里的 重写addCorsMappings方法配置一个 CorsRegistry 添加相应的路径方法与请求策略放行不就可以解决跨域的问题了?

    我们写一个WebMvcConfig配置类实现刚刚研究的WebMvcConfigurer接口重写addCrosMappings配置CrosRegistry即可(或者在api与Controller控制类上打上@CrossOrigin注解也可以解决问题(注解默认放行所有来源的请求)):

    /**
     * 配置前端跨域访问请求
     */
    @Configuration
    public class WbMvcConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
           registry.addMapping("/**")
                   .allowedHeaders("Content-Type","X-Request-With","Access-Control-Request-Method","Access-Control-Request-Headers","token")
                   .allowedMethods("*")
                   .allowedOriginPatterns("*")
                   /*注意当这个配置为真是我们不能将允许源设置为*而是将源路径设置为*即可*/
                   .allowCredentials(true);
        }
        @Bean
        public FormContentFilter httpPutFormContentFilter(){
            return new FormContentFilter();
        }
    }

    我们利用axios写一个简单的请求发送按钮:

        
        

    再用SpringBoot写一个简单的controller的api:

    @RestController
    public class testController {
        @Autowired
        private ProductServiceImpl productService;
        @GetMapping("/all")
        @ResponseBody
        public List all() {
            Page page = productService.page(1L);
            List productList = new LinkedList<>();
            productList.add(page.getRecords().iterator().next());
            return productList;
        }
    }

    这里我们在浏览器打开5050端口下的这个html文件就可以点击按钮访问接口了:

    Springboot怎么通过配置WebMvcConfig处理Cors非同源访问跨域问题

    这里可以看到请求访问数据成功了!

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    Go项目CORS跨域问题解决方法
    Go项目CORS跨域问题解决方法

    解决Go项目中CORS跨域问题的方法是配置正确的CORS头部信息,允许特定域访问API。1.使用中间件统一处理CORS,通过设置Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers头部实现集中管理;2.针对特定路由单独配置CORS规则;3.使用第三方库如github.com/rs/cors简化配置;4.处理OPTIONS预检请求并返回200OK状态码;5.若需携带cookie,设置Acce

    springBoot项目常用目录有哪些
    springBoot项目常用目录有哪些

    springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

    使用Flask-Cors解决Python web应用程序的跨域问题
    使用Flask-Cors解决Python web应用程序的跨域问题

    在开发Web应用程序时,跨域问题是一个很常见的问题。由于浏览器的同源策略限制,请求的发出必须要在当前域名下发出,否则就会受到限制。这就造成了不同域名下服务器之间的数据交互变得非常困难。为了解决这一问题,一种常用的方式是在服务器端做出相应的处理,即设置相应的跨域请求响应头。而Flask-Cors是一个优秀的解决跨域问题的Python库。Flask-Cors是什

    解析SpringBoot和SpringMVC之间的异同
    解析SpringBoot和SpringMVC之间的异同

    解析SpringBoot和SpringMVC之间的异同SpringBoot和SpringMVC是Java领域中非常重要的开发框架。虽然它们都属于Spring框架的一部分,但是在使用和功能上有一些明显的区别。本文将对SpringBoot和SpringMVC进行比较,解析它们之间的异同。首先,让我们来了解一下SpringBoot。SpringBo

    探索SpringCloud和SpringBoot在微服务领域的不同应用方式
    探索SpringCloud和SpringBoot在微服务领域的不同应用方式

    近年来,随着云计算和分布式架构的兴起,微服务架构的应用越来越广泛。而SpringCloud和SpringBoot作为Java开发中的两个重要框架,对于微服务的实现起到了重要的作用。然而,很多人对于它们在微服务领域的不同应用方式还存在一定的疑惑。本文将从不同的角度探索SpringCloud和SpringBoot在微服务中的应用方式。首先,我们来了解一下Spri

    SpringBoot和SpringMVC有何区别?
    SpringBoot和SpringMVC有何区别?

    SpringBoot与SpringMVC的不同之处在哪里?SpringBoot和SpringMVC是两个非常流行的Java开发框架,用于构建Web应用程序。尽管它们经常分别被使用,但它们之间的不同之处也是很明显的。首先,SpringBoot可以被看作是一个Spring框架的扩展或者增强版。它旨在简化Spring应用程序的初始化和配置过程,以帮助开发人

    比较SpringBoot和SpringMVC的异同
    比较SpringBoot和SpringMVC的异同

    SpringBoot和SpringMVC都是Java开发中常用的框架,但它们之间有一些明显的差异。本文将探究这两个框架的特点和用途,并对它们的差异进行比较。首先,我们来了解一下SpringBoot。SpringBoot是由Pivotal团队开发的,它旨在简化基于Spring框架的应用程序的创建和部署。它提供了一种快速、轻量级的方式来构建独立的、可执行

    SpringBoot与SpringMVC的不同点是什么?
    SpringBoot与SpringMVC的不同点是什么?

    SpringBoot和SpringMVC是Java开发中常用的两个框架,它们都是由Spring框架所提供的,但在功能和使用方式上有着一些区别。本文将分别介绍SpringBoot和SpringMVC的特点和区别。一、SpringBoot的特点:简化配置:SpringBoot通过约定优于配置的原则,大大简化了项目的配置过程。它可以自动配置项目所需要的参数,开发人

    比较和选择指南:SpringCloud与SpringBoot的功能比较
    比较和选择指南:SpringCloud与SpringBoot的功能比较

    SpringCloud和SpringBoot是目前Java领域中最热门的开源框架,它们分别提供了一套完善的微服务架构和快速构建应用程序的解决方案。本文将对它们的功能进行比较,并给出选择指南,以帮助读者了解它们的优势和适用场景。SpringBoot是一个用于开发Java应用程序的框架,它提供了一个简化的开发流程,集成了大量常用的功能和组件,减少了开发者的工作量

    SpringCloud与SpringBoot:分析它们之间的相似与不同
    SpringCloud与SpringBoot:分析它们之间的相似与不同

    深入剖析SpringCloud和SpringBoot的异同引言:在构建企业级应用程序时,Spring框架已经成为开发者们的首选。它提供了一种简单而强大的方式来构建独立于平台的应用程序。Spring框架由两个核心模块组成:SpringBoot和SpringCloud。虽然它们都可以帮助开发者快速搭建应用程序,但它们的目标和用途存在一些差异。本文将深入剖析Spr

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。