前后端跨域问题解决

前端:VUE,后端:spring boot

前后端跨域问题解决

问题:前端始终无法连接后端API

浏览器端报错:

Access to fetch at xxx from origin yyy has been blocked by CORS policy

请教老师,发现跨域问题要在后端解决,参考官方文档:https://www.baeldung.com/spring-cors

Cors跨域问题解决:

  1. 定义全局CORS设置:

  2. 在config目录下创建WebConfig.java,写下如下内容:

    package com.example.test.config;
    ​
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    ​
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    ​
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**")  // 允许所有路径
                            .allowedOrigins("*")  // 允许所有来源
                            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")  // 允许的HTTP方法
                            .allowedHeaders("*")  // 允许的请求头
                            .allowCredentials(true)  // 允许发送凭证
                            .maxAge(3600);  // CORS预检请求的缓存时间
                }
            };
        }
    }
    ​
  3. 使用前端访问进行测试,但还是显示:

    Access to fetch at 'http://localhost:8080/goods' from origin 'http://127.0.0.1:5501' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

    查阅资料,得知无论是使用“@CrossOrigin”还是全局cors设置,本质都是在http请求的盛恒加上“Access-Control-Allow-”标头,具体借鉴:SpringBoot 配置CORS处理前后端分离跨域配置无效问题解析 - 有来技术 - 博客园进行下一步的解决。

  4. 在config目录下新建CorsConfig.java,写:

    package com.example.test.config;
    ​
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    ​
    import java.util.Collections;
    ​
    /**
     * CORS资源共享配置
     *
     * @author haoxr
     * @date 2023/4/17
     */
    @Configuration
    public class CorsConfig {
    ​
        @Bean
        public FilterRegistrationBean filterRegistrationBean() {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            //1.允许任何来源
            corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
            //2.允许任何请求头
            corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
            //3.允许任何方法
            corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
            //4.允许凭证
            corsConfiguration.setAllowCredentials(true);
    ​
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", corsConfiguration);
            CorsFilter corsFilter = new CorsFilter(source);
    ​
            FilterRegistrationBean<CorsFilter> filterRegistrationBean=new FilterRegistrationBean<>(corsFilter);
            filterRegistrationBean.setOrder(-101);  // 小于 SpringSecurity Filter的 Order(-100) 即可
    ​
            return filterRegistrationBean;
        }
    }
    ​
    • 主要原理: SpringSecurityFilterChain 是先于 CorsFilter 执行的(重点), 如果是跨域请求浏览器会在正式请求前发出一次预检请求(OPTIONS),判断服务器是否允许跨域。

      跨域请求没到达 CorsFilter 过滤器就先被 Spring Security 的过滤器给拦截了,要知道预检 OPTIONS 请求是不带 token 的,所以响应 401 未认证的错误。预检请求失败导致后面的请求响应会被浏览器拦截。

    • 解决思路:

      配置 CorsFilter 优先于 SpringSecurityFilter 执行

    • 解决方案:

      Spring Security 过滤器是通过 SecurityFilterAutoConfiguration 的 DelegatingFilterProxyRegistrationBean 注册到 servletContext上下文,其中过滤器的顺序属性 Order 读取的 是 SecurityProperties 的默认配置也就是 -100;

    SpringBoot 可以通过 FilterRegistrationBean 来对 Filter 自定义注册(排序), 设置 Order 小于 SpringSecurity 的 -100 即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值