Flutter登录遇FormatException错误,寻求技术解决帮助
Flutter登录错误排查与修复
问题描述
开发Flutter应用(基于Dart语言,搭配MySQL数据库)时,登录环节持续触发以下错误:
I/flutter ( 7573): Error ::FormatException: Unexpected character (at character 1) I/flutter ( 7573): <br /> I/flutter ( 7573): ^
同时编写login.php时,输入fetch_assoc()无代码提示,怀疑该现象与登录报错相关。
相关代码文件
login.php代码
<?php include '../connection.php'; $userEmail = $_POST['EmailUser']; $userPassword = md5($_POST['PasswordUser']); $sqlQuery = "SELECT * FROM user_table WHERE EmailUser = '$userEmail' AND PasswordUser = '$userPassword'"; $resultOfQuery = $connectNow->query($sqlQuery); if($resultOfQuery->num_rows > 0)//allow user to login (record found) { $userRecord = array(); while($rowFound = $resultOfQuery->fetch_assoc()) { $userRecord[] = $rowFound; } echo json_decode( array( "success" =>true, "userData" =>$userRecord[0], ) ); } else// not allow if wrong either one { echo json_encode(array("success"=>false)); }
登录服务代码(Dart)
loginUserNow() async { try { var res = await http.post( Uri.parse(API.login), body: { "EmailUser": emailcontroller.text.trim(), "PasswordUser": passwordcontroller.text.trim(), }, ); if (res.statusCode == 200) //from flutter app to server connection suc { var resBodyOfLogin = jsonDecode(res.body); if (resBodyOfLogin['success'] == true) { Fluttertoast.showToast(msg: " you are Logged in Successfully."); User userInfo = User.fromJson(resBodyOfLogin["userData"]); //save user info to local storage usin the Shared Preference await RememberUserPrefs.saveRememberUser(userInfo); //send user to dashboard or default screen // ignore: prefer_const_constructors Get.to(DashboardOfFragments()); } else { Fluttertoast.showToast( msg: "Incorrect Credentials. Please try again."); } } } catch (errorMsg) { // ignore: avoid_print, prefer_interpolation_to_compose_strings print("Error ::$errorMsg"); } }
用户偏好设置代码(Dart)
import 'dart:convert'; import 'package:kezooapp/users/model/user.dart'; import 'package:shared_preferences/shared_preferences.dart'; class RememberUserPrefs { //save-remember User-info static Future<void> saveRememberUser(User userInfo) async { SharedPreferences preferences = await SharedPreferences.getInstance(); String userJsonData = jsonEncode(userInfo.toJson()); await preferences.setString("currentUser", userJsonData); } }
User模型代码(Dart)
class User { int IdUser; String NameUser; String EmailUser; String PasswordUser; User( this.IdUser, this.NameUser, this.EmailUser, this.PasswordUser, ); factory User.fromJson(Map<String, dynamic> json) => User( int.parse(json["IdUser"]), json["NameUser"], json["EmailUser"], json["PasswordUser"], ); Map<String, dynamic> toJson() => { 'IdUser': IdUser.toString(), 'NameUser': NameUser, 'EmailUser': EmailUser, 'PasswordUser': PasswordUser, }; }
解决方案
1. 修复PHP端核心错误
错误日志中的<br />是HTML错误提示,说明PHP输出了非JSON内容。问题出在成功登录分支的json_decode()调用——该函数用于解析JSON字符串,而非生成JSON,正确应使用json_encode():
// 修改后的成功分支代码 if($resultOfQuery->num_rows > 0) { $userRecord = array(); while($rowFound = $resultOfQuery->fetch_assoc()) { $userRecord[] = $rowFound; } // 替换json_decode为json_encode echo json_encode( array( "success" => true, "userData" => $userRecord[0], ) ); }
2. 解决PHP代码提示问题
fetch_assoc()无代码提示是因为编辑器无法识别$resultOfQuery的类型,可通过添加类型注释解决:
// 在$resultOfQuery声明前添加类型注释 /** @var mysqli_result $resultOfQuery */ $resultOfQuery = $connectNow->query($sqlQuery);
同时确保编辑器安装了PHP语法提示插件(如VSCode的PHP Intelephense),开启代码智能提示功能。
3. 修复SQL注入风险(可选但关键)
当前PHP代码直接拼接用户输入到SQL语句中,存在严重安全隐患,建议使用预处理语句替代:
// 替换原SQL查询与执行逻辑 $userEmail = $_POST['EmailUser']; $userPassword = md5($_POST['PasswordUser']); // 使用预处理语句 $sqlQuery = "SELECT * FROM user_table WHERE EmailUser = ? AND PasswordUser = ?"; $stmt = $connectNow->prepare($sqlQuery); // 绑定参数("ss"表示两个字符串类型参数) $stmt->bind_param("ss", $userEmail, $userPassword); $stmt->execute(); $resultOfQuery = $stmt->get_result();
4. Flutter端优化建议
- 在
loginUserNow()中添加响应内容打印,方便排查问题:
if (res.statusCode == 200) { print("Server Response: ${res.body}"); // 添加此行 var resBodyOfLogin = jsonDecode(res.body); // ... 后续逻辑 }
- 补充非200状态码的错误处理,覆盖服务器异常场景。
内容的提问来源于stack exchange,提问作者Yasmine
相关产品推荐
相关产品推荐

