springboot解决跨域问题

深碍√TFBOYSˉ_ 2023-10-12 20:18 132阅读 0赞

目录

跨域问题现象

跨域问题分析

什么是源和跨域

什么是同源策略?

Spring Boot:跨域问题解决

  1. 创建一个filter解决跨域

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

  3. controller配置CORS

@CrossOrigin不起作用的原因


" class="reference-link">watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZseTkxMDkwNQ_size_16_color_FFFFFF_t_70

跨域问题现象

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里,就可以优先于权限拦截器执行

  1. @Configuration
  2. public
  3. class
  4. CorsConfig {
  5. @Bean
  6. public CorsFilter
  7. corsFilter
  8. () {
  9. CorsConfiguration
  10. corsConfiguration
  11. =
  12. new
  13. CorsConfiguration();
  14. corsConfiguration.addAllowedOrigin(
  15. "*");
  16. corsConfiguration.addAllowedHeader(
  17. "*");
  18. corsConfiguration.addAllowedMethod(
  19. "*");
  20. corsConfiguration.setAllowCredentials(
  21. true);
  22. UrlBasedCorsConfigurationSource
  23. urlBasedCorsConfigurationSource
  24. =
  25. new
  26. UrlBasedCorsConfigurationSource();
  27. urlBasedCorsConfigurationSource.registerCorsConfiguration(
  28. "/**", corsConfiguration);
  29. return
  30. new
  31. CorsFilter(urlBasedCorsConfigurationSource);
  32. }
  33. }

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

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

  1. @Configuration
  2. public
  3. class
  4. CorsConfig
  5. implements
  6. WebMvcConfigurer {
  7. @Override
  8. public
  9. void
  10. addCorsMappings
  11. (CorsRegistry registry) {
  12. registry.addMapping(
  13. "/**")
  14. .allowedOrigins(
  15. "*")
  16. .allowCredentials(
  17. true)
  18. .allowedMethods(
  19. "GET",
  20. "POST",
  21. "PUT",
  22. "DELETE",
  23. "OPTIONS")
  24. .maxAge(
  25. 3600);
  26. }
  27. }

3. controller配置CORS

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

  1. @RestController
  2. @RequestMapping("/account")
  3. public
  4. class
  5. AccountController {
  6. @CrossOrigin
  7. @GetMapping("/{id}")
  8. public Account
  9. retrieve
  10. (@PathVariable Long id) {
  11. // ...
  12. }
  13. @DeleteMapping("/{id}")
  14. public
  15. void
  16. remove
  17. (@PathVariable Long id) {
  18. // ...
  19. }
  20. }

其中@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方式,具体指定后,问题解决。

类似代码如下:

  1. @CrossOrigin
  2. @RestController
  3. public
  4. class
  5. person{
  6. @RequestMapping(method = RequestMethod.GET)
  7. public String
  8. add
  9. () {
  10. // 若干代码
  11. }
  12. }

参考链接:

https://www.cnblogs.com/haha12/p/10564972.html

https://www.cnblogs.com/mmzs/p/9167743.html#_label1_0

发表评论

表情:
评论列表 (有 0 条评论,132人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Springboot解决问题

    (跨域资源共享)策略,允许跨域请求。常见的解决方法是在后端代码中添加CORS配置,允许特定的域名或所有域名的请求。可以使用Spring Boot提供的@CrossOrig...

    相关 springboot解决问题

        跨域是前后端分离,前端页面发起异步ajax请求,而浏览器因为同源策略导致请求失败,请求正确到了服务端,而且服务端也正常处理,只不过浏览器不认可,所以跨域问题的门槛是浏览