Cloudflare代理下的CORS异常:通过域名访问报“Invalid CORS request”,直接用IP正常
看起来你碰到了Cloudflare代理和Spring Boot CORS配置之间的冲突问题,我来帮你梳理一下可能的原因和解决方向,一步步排查:
1. 先修正Spring Boot的CORS Origin匹配规则
你当前配置的allowedOriginPatterns是"https://*.*.*",这个规则只能匹配三级及以上的HTTPS域名(比如https://sub.yourdomain.com),如果你的业务域名是二级域名(比如https://yourdomain.com),这个模式就完全匹配不上,这会直接导致Spring Boot返回"Invalid CORS request"。
建议修改成更适配的规则,比如:
@Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); // 允许所有HTTPS域名(测试用,生产建议换成你的具体域名) configuration.setAllowedOriginPatterns(Arrays.asList("https://*")); // 或者精准匹配你的业务域名 // configuration.setAllowedOriginPatterns(Arrays.asList("https://yourdomain.com")); configuration.setAllowedMethods(Arrays.asList("POST")); configuration.setAllowedHeaders(Arrays.asList("*")); configuration.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; }
你直接用IP访问正常,大概率是因为IP访问时的请求协议是HTTP,或者Origin头为空/符合其他默认规则,而走Cloudflare的域名是HTTPS且Origin是你的二级域名,刚好被当前的规则拦截了。
2. 排查Cloudflare的安全规则拦截
Cloudflare的WAF(Web应用防火墙)或者Bot管理规则,可能会把你的POST请求误判为恶意请求,直接返回403。你可以:
- 临时禁用WAF(在Cloudflare后台「Security > WAF」里操作)测试一下,如果恢复正常,说明是WAF规则拦截了请求,需要调整规则或者添加例外。
- 查看Cloudflare的「Security > Events」日志,确认有没有针对
/edit接口的拦截记录,根据日志提示调整规则。
3. 确认请求头是否被Cloudflare修改
Cloudflare代理后,可能会添加或修改部分请求头,比如CF-Connecting-IP、Host等,也有可能影响Origin头的传递。你可以在Spring Boot里加一个简单的过滤器,打印实际收到的请求头,看看Origin是否符合预期:
@Component public class RequestHeaderLogger extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { System.out.println("Received Origin: " + request.getHeader("Origin")); System.out.println("Received Host: " + request.getHeader("Host")); chain.doFilter(request, response); } }
启动服务后,触发请求查看日志,就能知道Spring Boot实际收到的Origin是不是你的域名,再对应调整CORS规则。
4. 检查Cloudflare的SSL/TLS模式
如果Cloudflare的SSL/TLS模式设置为「Flexible」,那么Cloudflare和你的Spring Boot服务器之间是HTTP通信,但用户端是HTTPS请求。这时候你的服务器收到的请求是HTTP,但请求的Origin是HTTPS,可能会导致CORS校验不通过。
建议把Cloudflare的SSL/TLS模式改成「Full」或者「Full (strict)」,确保Cloudflare和你的服务器之间也是HTTPS通信,保持协议一致性。
5. 补充fetch请求的凭证设置
你的Spring Boot配置允许了AllowCredentials(true),但fetch请求里没有设置凭证参数。如果你的请求需要携带Cookie或者其他凭证,需要在fetch里添加credentials: 'include':
fetch("/edit", { method: "POST", headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: data, credentials: 'include' // 新增这一行 }).then((resp) => { resp.json().then((res) => { if (res !== 200) { alert(typeof res); } }) })
不过你直接IP访问正常,这个可能不是核心问题,但可以作为补充检查项。
备注:内容来源于stack exchange,提问作者rmJay

