Flutter Web对接Spring Boot后端登录失败求助
Flutter Web 调用 Spring Boot 登录接口报错排查与解决
问题描述
开发基于Flutter Web的项目,后端采用Spring Boot框架,实现认证登录功能时遇阻:用Insomnia测试登录接口完全正常,但Flutter端调用时出现报错。当前登录页面代码如下:
import 'dart:convert'; import 'package:basic_utils/basic_utils.dart'; import 'dart:io'; import 'package:cryptoo/main.dart'; import 'package:cryptoo/screens/signup.dart'; import 'package:cryptoo/user.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:http/http.dart'; class SignInScreen extends StatefulWidget { static const kBackgroundColor = Colors.white; static const kPrimaryColor = Colors.amber; @override State<SignInScreen> createState() => _SignInScreenState(); } class _SignInScreenState extends State<SignInScreen> { final _formkey = GlobalKey<FormState>(); User user = User("", ""); String api = "192.168.1.105"; Future save() async { String url = "http://" + api + ":8011/users/login"; String username = user.username; String password = user.password; Map<String, String> headers = {"Accept": "application/json"}; var res = await http.post(Uri.parse(url), `problem here ....... headers: headers, body: jsonEncode({'username': 'Yosry1', 'password': 'Hamdi24963'})); print(res.statusCode); /*print(user.username); print(user.password);*/ if (res.statusCode == 200) { await Navigator.push( context, MaterialPageRoute(builder: (context) => HomeScreen())); print("connected"); } } var size, height, width; @override Widget build(BuildContext context) { size = MediaQuery.of(context).size; height = size.height; width = size.width; return Scaffold( body: Form( key: _formkey, child: Container( width: width, height: height, decoration: BoxDecoration( color: Color(0xff1f2630), ), padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: <Widget>[ Icon( Icons.alternate_email, color: SignInScreen.kPrimaryColor, ), Container( padding: EdgeInsets.all(10), width: width * 0.8, child: TextFormField( controller: TextEditingController(text: user.username), onChanged: (val) { user.username = val; }, validator: (value) { if (value!.isEmpty) { return 'Username is Empty'; } return null; }, decoration: InputDecoration( hintStyle: TextStyle(color: Colors.white), hintText: "Username", ), ), ) ], ), Row( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Icon( Icons.lock, color: SignInScreen.kPrimaryColor, ), Container( padding: EdgeInsets.all(10), width: width * 0.8, child: TextFormField( controller: TextEditingController(text: user.password), onChanged: (val) { user.password = val; }, validator: (value) { if (value!.isEmpty) { return 'Password is Empty'; } return null; }, decoration: InputDecoration( hintStyle: TextStyle(color: Colors.white), hintText: "Password", ), ), ), ], ), TextButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => SignUpScreen(), )); }, child: Text("SingUp"), ), SizedBox(height: 5), Container( width: width * 0.7, height: 50, child: ElevatedButton( onPressed: () async { /* Navigator.push( context, MaterialPageRoute( builder: (context) => HomeScreen();*/ //if (_formkey.currentState!.validate()) {} save(); }, child: Text("SignIn"), ), ), ], ), ), ), ); } }
排查与修复步骤
1. 修复代码语法错误
代码中http.post调用行存在多余的反引号,直接导致语法报错,同时当前硬编码了测试账号,应替换为用户输入内容:
// 错误代码 var res = await http.post(Uri.parse(url), `problem here ....... headers: headers, body: jsonEncode({'username': 'Yosry1', 'password': 'Hamdi24963'})); // 修正后代码 var res = await http.post(Uri.parse(url), headers: headers, body: jsonEncode({'username': user.username, 'password': user.password}));
2. 补充请求头参数
Spring Boot接口需要明确识别请求体格式,当前仅添加了Accept头,需补充Content-Type:
Map<String, String> headers = { "Accept": "application/json", "Content-Type": "application/json" };
3. 解决CORS跨域问题(核心)
Flutter Web运行在浏览器环境下受同源策略限制,这是接口测试正常但前端调用失败的最常见原因。需要在Spring Boot端配置CORS:
- 全局配置示例:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:5000") // 替换为你的Flutter Web运行地址 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true); } }
- 或在登录接口方法上添加注解:
@CrossOrigin(origins = "http://localhost:5000") @PostMapping("/users/login") public ResponseEntity<?> login(@RequestBody UserLoginRequest request) { // 登录逻辑实现 }
4. 捕获并输出详细错误信息
修改save方法,捕获异常并打印完整错误信息,方便定位问题:
Future save() async { try { String url = "http://" + api + ":8011/users/login"; Map<String, String> headers = { "Accept": "application/json", "Content-Type": "application/json" }; var res = await http.post(Uri.parse(url), headers: headers, body: jsonEncode({'username': user.username, 'password': user.password})); print("状态码: ${res.statusCode}"); print("响应内容: ${res.body}"); if (res.statusCode == 200) { await Navigator.push( context, MaterialPageRoute(builder: (context) => HomeScreen())); print("登录成功"); } else { print("登录失败: ${res.body}"); } } catch (e) { print("请求异常: $e"); } }
5. 验证网络连通性
确保Flutter Web运行设备能访问192.168.1.105:8011,可直接在浏览器中输入接口地址测试是否能正常响应。
内容的提问来源于stack exchange,提问作者Mohamed hedi Hamdi
相关产品推荐
相关产品推荐

