Spring Boot中特定GET接口CORS跨域报错,POST接口正常求解决方案
解决Spring Boot特定GET接口CORS跨域问题的方案
核心现象:仅/on-fetch-return接口触发CORS错误(提示缺少Access-Control-Allow-Origin响应头),其他接口正常,已配置全局CORS和@CrossOrigin但无效。以下是针对性排查和解决步骤:
1. 排查404导致的CORS“假象”
浏览器对404响应会优先提示CORS错误,而非真实的404状态。你的接口逻辑中,当concurrentMap不存在请求的key时会返回404:
if (concurrentMap.get(key) != null) { // 返回正常响应 } else return ResponseEntity.notFound().build();
- 直接用浏览器地址栏或Postman调用该接口,确认是否返回404
- 检查请求的
key=5f7a535d-a3fd-416b-b069-c97d021fbacd是否确实存在于concurrentMap中
若为404导致,先解决接口可达性问题,CORS错误会随之消失
2. 检查控制器路径前缀匹配
AJAX请求路径是/v0.5/users/auth/on-fetch-return,但控制器仅标注@GetMapping("/on-fetch-return"),需确认控制器类是否添加对应前缀:
// 必须添加该前缀,否则接口实际路径为/on-fetch-return,会导致404 @RequestMapping("/v0.5/users/auth") public class ABDMSandboxController { // ... 接口代码 }
3. 修复Spring Security的CORS配置冲突
Spring Boot 2.4+版本中,setAllowedOrigins与setAllowedOriginPatterns存在优先级冲突,推荐仅保留后者,同时补充凭证允许配置:
@Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration conf = new CorsConfiguration(); conf.setAllowedHeaders(Collections.singletonList("*")); // 移除setAllowedOrigins,避免冲突 // conf.setAllowedOrigins(Collections.singletonList("*")); conf.setAllowedOriginPatterns(Collections.singletonList("*")); conf.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")); conf.setAllowCredentials(true); // 允许携带凭证(如Cookie) UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", conf); return source; }
同时确保HttpSecurity中cors()配置在最前面:
@Override protected void configure(HttpSecurity http) throws Exception { http.cors() // 优先处理CORS .and() .csrf().disable() // 其他拦截规则... }
4. 强制为所有响应添加CORS头
当接口返回错误状态(如404)时,Spring默认CORS过滤器可能未介入,可通过自定义高优先级过滤器强制添加头:
@Component @Order(Ordered.HIGHEST_PRECEDENCE) public class CustomCorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest request = (HttpServletRequest) req; response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept"); response.setHeader("Access-Control-Allow-Credentials", "true"); if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { chain.doFilter(req, res); } } @Override public void init(FilterConfig filterConfig) {} @Override public void destroy() {} }
5. 清理AJAX冗余配置
GET请求无需设置contentType(无请求体),crossOrigin: true为jQuery冗余配置,可移除:
function getfetchmodesreturn() { $.ajax({ type: 'GET', url: GATEWAY_HOST+"/v0.5/users/auth/on-fetch-return?key=5f7a535d-a3fd-416b-b069-c97d021fbacd", dataType: "json", headers: { 'Authorization': 'Bearer ' + sessionStorage.getItem("accessToken"), 'accept':'*/*', }, success: function (data) { console.log("return data =====================",data); console.log(data); }, error: function (error) { console.log("On Error"); console.log(error); } }); }
内容的提问来源于stack exchange,提问作者ameya Patil
相关产品推荐
相关产品推荐

