如何为Flutter Web应用配置Spring Boot API的CORS跨域支持
解决Flutter Web调用Spring Boot API的CORS错误及代码问题
1. 控制器方法命名错误(核心问题)
你的AuthenticationController代码中,@PostMapping("/authenticate")注解下的方法名错误写成了register,和上方的注册方法重名。这会导致Spring无法正确映射请求,请求到达时会抛出异常,无法返回CORS相关响应头,直接触发CORS错误。
修正代码:
@RestController @RequestMapping("/api/v1/auth") class AuthenticationController( private val authenticationService: AuthenticationService ) { @PostMapping("/register") fun register( @RequestBody request: RegisterRequestBody ): ResponseEntity<AuthenticationResponse> { return ResponseEntity.ok(authenticationService.register(request)) } // 修正方法名为authenticate @PostMapping("/authenticate") fun authenticate( @RequestBody request: AuthenticationRequest ): ResponseEntity<AuthenticationResponse> { return ResponseEntity.ok(authenticationService.authenticate(request)) } }
2. Flutter请求缺少Content-Type头
你用jsonEncode序列化了请求体,但未设置Content-Type: application/json请求头,导致Spring无法识别请求体格式,触发的OPTIONS预检请求(preflight)无法得到正确处理,进而引发CORS错误。
修正Flutter请求代码:
class AuthenticationApi { var uri = Uri.http("localhost:8080","/api/v1/auth/authenticate"); Future<String?> loginWithCredentials(String username, String password) async { var body = jsonEncode(loginBody(username, password)); final response = await http.post( uri, body: body, // 添加JSON格式请求头 headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { return response.body; } else { return null; } } }
3. 确保CORS配置全局生效
如果上述两点修正后仍有问题,建议配置全局CORS过滤器,确保覆盖所有API路径:
创建CORS配置类:
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 @Configuration class CorsConfig { @Bean fun corsFilter(): CorsFilter { val config = CorsConfiguration() // 允许你的Flutter Web来源 config.addAllowedOrigin("http://localhost:53289") // 允许所有请求方法 config.addAllowedMethod("*") // 允许所有请求头 config.addAllowedHeader("*") // 允许携带凭证(如Cookie,按需开启) config.allowCredentials = true val source = UrlBasedCorsConfigurationSource() // 对所有API路径应用CORS规则 source.registerCorsConfiguration("/api/**", config) return CorsFilter(source) } }
若使用@CrossOrigin注解,建议加到控制器类上覆盖所有方法:
@RestController @RequestMapping("/api/v1/auth") @CrossOrigin(origins = ["http://localhost:53289"], allowedHeaders = ["*"], methods = [RequestMethod.POST]) class AuthenticationController(...) { // ... 方法实现 }
内容的提问来源于stack exchange,提问作者Ben Johnson
相关产品推荐
相关产品推荐

