Springboot之跨域问题

我爱海鲸 2026-02-06 17:32:17 bug

简介跨域问题

今天发布博客版本的时候出现了一个跨域的问题,少废话,上源码:

package xyz.haijin.weblog.config;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 1 设置访问源地址
//        corsConfiguration.addAllowedOrigin("*");
        // 2 设置访问源请求头
        corsConfiguration.addAllowedHeader("*");
        // 3 设置访问源请求方法
        corsConfiguration.addAllowedMethod("*");

        corsConfiguration.setAllowCredentials(true);
        //如果springboot的版本是高版本的,如:2.6.2,需要修改corsConfiguration.addAllowedOrigin("*")为:corsConfiguration.addAllowedOriginPattern("*");
        corsConfiguration.addAllowedOriginPattern("*");

        // 4 暴露哪些头部信息
//        corsConfiguration.addExposedHeader(JwtConstant.HEADER);
        return corsConfiguration;
    }

    //解决跨域
//    @Bean
//    public CorsWebFilter corsWebFilter() {
//        CorsConfiguration config = new CorsConfiguration();
//        config.addAllowedMethod("*");
//        config.addAllowedOrigin("*");
//        config.addAllowedHeader("*");
//        config.addAllowedOriginPattern("*");
//
//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
//        source.registerCorsConfiguration("/**",config);
//
//        return new CorsWebFilter(source);
//    }

    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
//        跨域配置CorsFilter不生效原因
//        项目中有多个Filter时,需要通过 @Order(Ordered.HIGHEST_PRECEDENCE) 注解设置过滤器的执行顺序
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 5 对接口配置跨域设置
        source.registerCorsConfiguration("/**", buildConfig());
        //有多个filter时此处设置改CorsFilter的优先执行顺序
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

2026-02-06 start:

springboot3.5.9

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 跨域配置类
 * 允许所有来源跨域(不携带 Cookie 场景)
 *
 * @author system
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {

    /**
     * 配置跨域映射
     *
     * @param registry 跨域注册器
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                // 允许所有来源跨域(无需指定具体地址)
                .allowedOriginPatterns("*")
                .allowedHeaders("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH")
                .exposedHeaders("*")
                // 关键:关闭允许携带 Cookie(与 * 通配符兼容)
                .allowCredentials(false)
                .maxAge(3600);
    }

    /**
     * 配置CORS过滤器
     * 用于处理预检请求(OPTIONS),设置最高优先级确保先执行
     *
     * @return CORS过滤器注册Bean
     */
    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();

        // 允许所有源(使用OriginPattern支持通配符)
        config.addAllowedOriginPattern("*");

        // 允许所有请求头(包括Authorization)
        config.addAllowedHeader("*");
        config.addAllowedHeader("Authorization");
        config.addAllowedHeader("Content-Type");
        config.addAllowedHeader("Accept");

        // 允许所有请求方法
        config.addAllowedMethod("*");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("PATCH");

        // 暴露所有响应头
        config.addExposedHeader("*");

        // 不允许携带凭证(与allowedOriginPattern("*")配合使用)
        // 注意:即使Authorization头存在,只要allowCredentials为false,就不会触发凭证检查
        config.setAllowCredentials(false);

        // 预检请求的缓存时间(秒)
        config.setMaxAge(3600L);

        // 对所有路径生效
        source.registerCorsConfiguration("/**", config);

        // 创建过滤器注册Bean,设置最高优先级
        FilterRegistrationBean<CorsFilter> registration = new FilterRegistrationBean<>(new CorsFilter(source));
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        registration.setName("corsFilter");

        return registration;
    }
}

end

你好:我的2025