Spring Boot:如何解决跨域问题 ?

本文涉及的产品
.cn 域名,1个 12个月
简介: 跨域问题的原因:浏览器出于安全考虑,限制访问本站点以为的资源。

111.jpeg

跨域问题现象

been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource

上面的意思就是  你访问一个什么地址被CORS 协议阻止, 没有 在Hearder 里面发现 Access-Control-Allow-Origin 的参数的 资源

跨域问题分析

跨域问题的原因:浏览器出于安全考虑,限制访问本站点以为的资源

比如你有一个 网站 127.0.0.1:8080/ , 并且上面挂了一个页面 ,那么在这个页面中 ,你只访问 本站点的 资源不会受到限制,但是你如果访问其他站点,比如  127.0.0.1:8081 的资源就会受到限制。

备注:暂且把  协议,域名,端口都一样的叫做同一个站点。

但是  带有 src 属性的标签可以没有这个 限制,比如 img ,script  等等。

在说说历史,以前的程序前后端不分离, 页面 和 请求接口,在同一个 域名同一个端口下面。 所有 浏览器认为来源这个 站点的页面 ,请求的是同一个站点的 接口,那么久会允许。

比如 127.0.0.1:8080/index.html  ,请求 127.0.0.1:8080/a/b/c/userLit 接口,这样是可以的

在说说现在,前后点分离,页面 和接口一般不是一个程序,这样就不允许,就会抛出这个异常

什么是源和跨域

源(origin)就是协议、域名和端口号。

URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口全部相同,则表示他们同源。否则,只要协议、域名、端口有任何一个不同,就是跨域。

https://www.baidu.com/index.html进行跨域比较:

URL 是否跨域 原因
https://www.baidu.com/more/index.html 不跨域 三要素相同
https://map.baidu.com/ 跨域 域名不同
http://www.baidu.com/index.html 跨域 协议不同
https://www.baidu.com:81/index.html 跨域 端口号不同

什么是同源策略?

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略又分为以下两种:

    1. DOM同源策略:禁止对不同源页面DOM 进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
    2. XMLHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。

    Spring Boot:跨域问题解决

    1. 创建一个filter解决跨域

    项目中前后端分离部署,所以需要解决跨域的问题。 我们使用cookie存放用户登录的信息,在spring拦截器进行权限控制,当权限不符合时,直接返回给用户固定的json结果。 当用户登录以后,正常使用;当用户退出登录状态时或者token过期时,由于拦截器和跨域的顺序有问题,出现了跨域的现象。 我们知道一个http请求,先走filter,到达servlet后才进行拦截器的处理,如果我们把cors放在filter里,就可以优先于权限拦截器执行

    @Configuration
    public class CorsConfig {
        @Bean
        public CorsFilter corsFilter() {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedOrigin("*");
            corsConfiguration.addAllowedHeader("*");
            corsConfiguration.addAllowedMethod("*");
            corsConfiguration.setAllowCredentials(true);
            UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
            urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
            return new CorsFilter(urlBasedCorsConfigurationSource);
        }
    }

    image.gif

    2. 基于WebMvcConfigurerAdapter配置加入Cors的跨域

    跨域可以在前端通过 JSONP 来解决,但是 JSONP 只可以发送 GET 请求,无法发送其他类型的请求,在 RESTful 风格的应用中,就显得非常鸡肋,因此我们推荐在后端通过 (CORS,Cross-origin resource sharing) 来解决跨域问题。这种解决方案并非 Spring Boot 特有的,在传统的 SSM 框架中,就可以通过 CORS 来解决跨域问题,只不过之前我们是在 XML 文件中配置 CORS ,现在可以通过实现WebMvcConfigurer接口然后重写addCorsMappings方法解决跨域问题

    @ConfigurationpublicclassCorsConfigimplementsWebMvcConfigurer {
    @OverridepublicvoidaddCorsMappings(CorsRegistryregistry) {
    registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowCredentials(true)
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                    .maxAge(3600);
        }
    }

    image.gif

    3. controller配置CORS

    controller方法的CORS配置,您可以向@RequestMapping注解处理程序方法添加一个@CrossOrigin注解,以便启用CORS(默认情况下,@CrossOrigin允许在@RequestMapping注解中指定的所有源和HTTP方法):

    @RestController@RequestMapping("/account")
    publicclassAccountController {
    @CrossOrigin@GetMapping("/{id}")
    publicAccountretrieve(@PathVariableLongid) {
    // ...    }
    @DeleteMapping("/{id}")
    publicvoidremove(@PathVariableLongid) {
    // ...    }
    }

    image.gif

    其中@CrossOrigin中的参数:

    @CrossOrigin 表示所有的URL均可访问此资源 @CrossOrigin(origins = “http://127.0.0.1:8080”)//表示只允许这一个url可以跨域访问这个controller 代码说明:@CrossOrigin这个注解用起来很方便,这个可以用在方法上,也可以用在类上。如果你不设置他的value属性,或者是origins属性,就默认是可以允许所有的URL/域访问。

      1. value属性可以设置多个URL。
      2. origins属性也可以设置多个URL。
      3. maxAge属性指定了准备响应前的缓存持续的最大时间。就是探测请求的有效期。
      4. allowCredentials属性表示用户是否可以发送、处理 cookie。默认为false
      5. allowedHeaders 属性表示允许的请求头部有哪些。
      6. methods 属性表示允许请求的方法,默认get,post,head。

      @CrossOrigin不起作用的原因

      1、是springMVC的版本要在4.2或以上版本才支持@CrossOrigin

      2、非@CrossOrigin没有解决跨域请求问题,而是不正确的请求导致无法得到预期的响应,导致浏览器端提示跨域问题。

      3、在Controller注解上方添加@CrossOrigin注解后,仍然出现跨域问题,解决方案之一就是:

      在@RequestMapping注解中没有指定Get、Post方式,具体指定后,问题解决。

      类似代码如下:

      @CrossOrigin@RestControllerpublicclassperson{
      @RequestMapping(method=RequestMethod.GET)
      publicStringadd() {
      // 若干代码    }
      }

      image.gif

      目录
      相关文章
      |
      1月前
      |
      JavaScript 前端开发 Java
      springboot解决js前端跨域问题,javascript跨域问题解决
      本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
      springboot解决js前端跨域问题,javascript跨域问题解决
      |
      23天前
      |
      安全 Java 应用服务中间件
      SpringBoot:CORS是什么?SpringBoot如何解决跨域问题?
      CORS是Web开发中常见且重要的机制,SpringBoot通过提供注解、全局配置和过滤器等多种方式来解决跨域问题。选择适合的方式可以帮助开发者轻松处理跨域请求,提高应用的灵活性和安全性。
      52 2
      |
      1月前
      |
      前端开发 安全 Java
      springboot解决跨域问题
      跨域问题指前端调用与后端接口不在同一域名或端口时产生的安全限制。本文介绍两种在Spring Boot中解决跨域问题的方法:一是通过配置CorsFilter,二是实现WebMvcConfigurer接口。配置完成后重启项目即可生效。作者:博笙困了。来源:稀土掘金。
      |
      1月前
      |
      安全 JavaScript Java
      SpringBoot解决跨域最佳实践
      本文介绍了跨域问题的起因及最佳实践,重点讲解了SpringBoot中如何利用`CorsFilter`解决跨域问题。首先解释了由于浏览器的同源策略限制导致的跨域现象,然后提出了在服务端入口处解决跨域问题的建议,最后详细展示了三种SpringBoot中配置跨域的方法:使用默认配置、自定义配置规则以及通过配置文件管理跨域设置,以适应不同的应用场景。
      |
      1月前
      |
      前端开发 安全 JavaScript
      SpringBoot 如何解决跨域问题?
      本文深入探讨了Spring Boot解决跨域问题的方法,包括全局配置CORS、使用@CrossOrigin注解和自定义过滤器,提供了详细的代码示例和分析,帮助开发者有效应对Web开发中的跨域挑战。
      |
      1月前
      |
      存储 运维 安全
      Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
      通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
      44 2
      |
      2月前
      |
      JavaScript 前端开发 Java
      解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
      这篇文章详细介绍了如何在前端Vue项目和后端Spring Boot项目中通过多种方式解决跨域问题。
      402 1
      解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
      |
      2月前
      |
      SQL JSON Java
      mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
      这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
      78 1
      mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
      |
      2月前
      |
      Java 数据库连接 API
      springBoot:后端解决跨域&Mybatis-Plus&SwaggerUI&代码生成器 (四)
      本文介绍了后端解决跨域问题的方法及Mybatis-Plus的配置与使用。首先通过创建`CorsConfig`类并设置相关参数来实现跨域请求处理。接着,详细描述了如何引入Mybatis-Plus插件,包括配置`MybatisPlusConfig`类、定义Mapper接口以及Service层。此外,还展示了如何配置分页查询功能,并引入SwaggerUI进行API文档生成。最后,提供了代码生成器的配置示例,帮助快速生成项目所需的基础代码。
      166 1
      |
      2月前
      |
      缓存 NoSQL Java
      Springboot自定义注解+aop实现redis自动清除缓存功能
      通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
      88 2