You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2023与React自定义Header的CORS问题排查

错误原因分析
  1. "允许源设为*时不能启用凭证"错误
    浏览器的CORS安全规则明确要求:当请求携带credentials(Cookie、HTTP认证信息或客户端SSL证书)时,Access-Control-Allow-Origin响应头不能设置为通配符*,必须返回与请求的Origin头完全匹配的具体域名,否则浏览器会直接拦截响应。

  2. 预检请求无Access-Control-Allow-Origin头错误
    你的请求包含自定义CustomAuth头且携带凭证,属于复杂请求,浏览器会先发送OPTIONS预检请求验证服务器是否允许该请求。如果服务器未正确处理OPTIONS请求,未返回Access-Control-Allow-Origin等必要CORS响应头,浏览器就会拦截后续的实际业务请求。

解决方案

1. Spring Boot 全局CORS配置(动态适配任意请求源)

通过全局配置动态获取请求的Origin头作为允许的源,同时开启凭证支持,允许自定义头并正确处理预检请求:

方式一:使用Spring官方CorsFilter(Spring Boot 2.4+推荐)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        // 开启凭证支持
        config.setAllowCredentials(true);
        // 允许任意合法请求源(用originPattern适配动态源,支持带凭证的请求)
        config.addAllowedOriginPattern("*");
        // 允许所有HTTP请求方法
        config.addAllowedMethod("*");
        // 允许自定义头CustomAuth及常用请求头
        config.addAllowedHeader("CustomAuth");
        config.addAllowedHeader("Content-Type");
        config.addAllowedHeader("Accept");
        // 设置预检请求缓存时长(秒),避免重复发送OPTIONS请求
        config.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 对所有接口生效
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

方式二:自定义Filter适配旧版本Spring Boot

如果使用Spring Boot 2.4之前的版本,可通过自定义Filter动态获取请求Origin并设置响应头:

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Configuration
public class CorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        String origin = request.getHeader("Origin");
        
        // 动态设置允许的源为请求的Origin
        response.setHeader("Access-Control-Allow-Origin", origin);
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "CustomAuth, Content-Type, Accept");

        // 直接响应预检请求,无需转发到业务接口
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return;
        }
        chain.doFilter(req, res);
    }
}

2. 控制器接口接收自定义头

在/months接口中通过@RequestHeader获取CustomAuth头:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MonthController {
    @GetMapping("/months")
    public Object getMonths(@RequestHeader("CustomAuth") String customAuth) {
        // 此处编写业务逻辑
        return yourMonthData;
    }
}

3. React客户端fetch请求配置

确保请求携带凭证并正确设置自定义头:

// 登录请求示例
fetch('/login', {
  method: 'POST',
  credentials: 'include', // 携带Cookie等凭证
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(loginFormData)
})

// 获取月份请求示例
fetch('/months', {
  method: 'GET',
  credentials: 'include',
  headers: {
    'CustomAuth': yourAuthToken // 携带自定义认证头
  }
})
关键注意事项
  • 不要同时使用全局CORS配置和控制器上的@CrossOrigin注解,避免配置冲突。
  • Android端不受浏览器CORS规则限制,上述配置也能正常支持Android的HTTP请求。

内容的提问来源于stack exchange,提问作者Clown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:20:19