Vue + Springboot 前后端分离项目——跨域问题


跨域问题

什么是跨域?比如,
- 前端vue项目服务启动后访问路径是 http:localhost:8080 ,
- 后端springboot项目服务启动后访问路径是 http:localhost:8081,

然后前端向后端接口发送里一个请求是 http:localhost:8081/list(假设有一个查询的请求),这时候这个接口请求被浏览器的CORS策略阻止了。 其实,这个”阻止“是由于浏览器的一个保护机制,并不是说这个后端没有接收到请求(如果后端没有接收到请求,请自觉自我反省、检查),打断点会发现后端是接收到了请求并且将请求返回了的[这里代码、截图下次补上]。

那么,前端请求发送到了后端,后端收到请求并返回了相关的数据却因为浏览器的这个保护机制将后端的响应拦截所造成的跨域问题如何解决呢? 首先明白浏览器为什么这么干?前面说是保护机制,没错,但要具体的说者涉及到浏览器的一个 ‘同源策略’。 同源策略是浏览器的很重要的安全策略(有点废话了,为了以后看得明白无所谓了),它的作用是:为了限制不同源之间的交互,从而避免一些浏览器层面的攻击。 那问题来了,什么是同源?不同源又是啥? 通俗的讲,发送请求就是浏览器地址栏上的一个地址嘛,一个url地址。url中肯定包含了这个请求的协议、域名、端口, 那么此时此刻这三哥们必须同时相同就是同源,它们三个只要有一个不同那就是不同源。好理解吧!那看下面的:

vue:http:localhost:8080
Springboot:http:localhost:8081/list

它俩一对比就发现,协议 ‘http’ 一样、域名 ‘localhost’一样,端口不一致.这就造成了不同源。 但是,前后端分离开发这个模式,前端和后端就是两个独立的应用是吧,这是必然的会不符合同源的策略。 那这里就需要咱们手动的去解决这个问题,在咱们后端改一下这个配置。 这里插个知识点:CORS策略(Cross Origin Resource Sharing,用赞,咱们中文说人话就是 跨域资源共享,就是如果出现跨域的话就允许它进行这个资源的共享 ),通俗的讲它是由一系列的http头组成的。 那么,我们在这个CORS里的http头中添加相关配置允许它去读取这个不同源地址返回的响应就ok了。 这里主要介绍咱们后端方面怎么解决。三种方案:

  • 比如前端请求的后端的地址是 http:localhost:8081/list,端口号后面的这个list代表它具体访问的是哪个接口对应的那个方法,有的请求是端口号后面跟着两个,如图我们只要找到它具体访问的那个方法就行. 在请求具体访问的那个方法上加上注解 @CrossOrigin

  • 如果后端的方法很多呢?再这么加注解是不是显得很low。那么第二种方案来了!添加一个过滤器,统一的解决这一类地址的请求,让这一类的请求都可以访问。 在咱们Springboot项目中通常会有一个配置类的目录有很多的配置类,我们就可以将这个过滤器创建在这个目录下,在这个配置类里注入咱们这个过滤器。

    @Configuration public class GlobalCorsConfig {

     @Bean
     public CorsFilter corsFilter() {
    
         //1.添加CORS配置信息  创建这个对象  CorsConfiguration
         CorsConfiguration config = new CorsConfiguration();
    
         //1) 这个是添加允许哪些域可以访问    允许的域,不要写*,否则cookie就无法使用了
         config.addAllowedOrigin("http://127.0.0.1:8081");
    
         config.addAllowedOrigin("http://localhost:8081");
    
         config.addAllowedOrigin("http://127.0.0.1:8082");
    
         config.addAllowedOrigin("http://localhost:8082");
    
         //1.1)
         /*这个是添加允许哪些域可以访问    添加允许的域,也是可以写 通配符 * ,但会使cookie就无法使用了
          config.addAllowedOrigin("*");
         二选一 */
    
    
         //2) 是否发送Cookie信息
         config.setAllowCredentials(true);
    
         //3) 这个是添加允许访问域的请求方式  允许的请求方式
         config.addAllowedMethod("OPTIONS");
    
         config.addAllowedMethod("HEAD");
    
         config.addAllowedMethod("GET");
    
         config.addAllowedMethod("PUT");
    
         config.addAllowedMethod("POST");
    
         config.addAllowedMethod("DELETE");
    
         config.addAllowedMethod("PATCH");
    
         // 4)允许的头信息,就是请求头字段   通配符表示  我allin  梭哈懂我意思吧  都允许
         config.addAllowedHeader("*");
    
         //2.添加映射路径,我们拦截一切请求
         //创建source对象
         UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
    
         configSource.registerCorsConfiguration("/**", config);
    
         //3.返回新的CorsFilter.
         return new CorsFilter(configSource);
    
     }
    

    }

注意:使用过滤器统一管理的时候不要使用单个注解的方式了
  • 创建一个配置类去实现一个接口 WebMvcConfigurer,重写addCorsMappings方法 和上面的过滤器差不多的意思,这个添加的就是允许哪些地址能访问

    @Configuration public class MvcConfig implements WebMvcConfigurer {

     @Autowired
     private LoginCheckInterceptor loginCheckInterceptor;
    
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         //将自定义的拦截器,添加到Springmvc的配置中,这样就可以生效
         registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**")
                 .excludePathPatterns(
                         "/user/login","/file/upload","/shop/register",
                         "/user/sendmobilecode/**","/user/checkphone/**",
                         "/user","/wechart/**"
                 );
    
     }
    

    }

注意:以上三种方法不能同时使用,既然是配置类让它实现同样的效果,不同的配置方法多少会存在差异。

切记,三选一就行

JAVA-技能点
知识点