Flutter Dart解析JSON遇FormatException异常求助
Flutter解析PHP返回JSON触发FormatException的解决方案
问题说明
使用Flutter的fetchTodos函数从PHP接口获取数据时,触发FormatException异常,错误提示响应内容开头存在意外字符。实际返回内容以"Connected"开头,无法转换为List类型。
错误信息
I/flutter (25473): The error: FormatException: Unexpected character (at character 1) I/flutter (25473): Connected[{"id":"1","taskId":"1","todoInfo":"Productos Autos"},{"id":"2","t... I/flutter (25473): ^
原Flutter代码
import "dart:convert"; import "package:flutter/material.dart"; import "package:flutter_application_db/models/todo_model.dart"; import "package:scoped_model/scoped_model.dart"; import "package:http/http.dart" as http; mixin TodoModel on Model { final List<Todo> _todos = []; final url = Uri.parse("http://192.168.1.66/api_rest/query/sql_get_all.php"); List<Todo> get todo => List.from(_todos); void fetchTodos() async { try { final http.Response response = await http.get( url, ); final List<dynamic> responseDecoded = json.decode(response.body); debugPrint("The response decoded: $responseDecoded"); } catch (e) { print("The error: $e"); } //print(response); } }
问题根源
PHP接口输出了额外的调试信息("Connected"),导致返回的内容不是标准JSON格式,Flutter的json.decode只能解析纯JSON字符串,因此抛出异常。
解决方案
方案1:修正PHP接口(推荐)
确保PHP接口仅输出标准JSON数据,移除所有非JSON的输出内容:
- 检查PHP文件,删除类似
echo "Connected";的调试语句; - 添加响应头声明内容为JSON格式,确保输出的JSON字符串没有多余字符。
示例PHP代码修正:
<?php // 数据库连接配置 $servername = "localhost"; $username = "your_username"; $password = "your_password"; $dbname = "your_db"; // 创建连接 $conn = mysqli_connect($servername, $username, $password, $dbname); // 检查连接(不要输出"Connected") if (!$conn) { // 错误时输出JSON格式的错误信息 header('Content-Type: application/json'); echo json_encode(['error' => mysqli_connect_error()]); exit; } // 执行查询 $sql = "SELECT * FROM todos"; $result = mysqli_query($conn, $sql); // 获取数据并转为JSON $data = mysqli_fetch_all($result, MYSQLI_ASSOC); header('Content-Type: application/json'); echo json_encode($data); // 关闭连接 mysqli_close($conn); ?>
方案2:Flutter端临时过滤(不推荐)
若暂时无法修改PHP接口,可在Flutter中先过滤掉开头的非JSON内容再解析:
void fetchTodos() async { try { final http.Response response = await http.get(url); // 移除开头的"Connected"字符串 String cleanResponse = response.body.replaceFirst('Connected', '').trim(); final List<dynamic> responseDecoded = json.decode(cleanResponse); debugPrint("The response decoded: $responseDecoded"); // 将解析后的数据映射到Todo模型并更新列表 _todos.clear(); _todos.addAll(responseDecoded.map((item) => Todo.fromJson(item)).toList()); notifyListeners(); } catch (e) { print("The error: $e"); } }
注意:此方案仅为临时 workaround,核心问题仍在于PHP接口输出不规范,优先采用方案1解决。
内容的提问来源于stack exchange,提问作者Alviore De Röl
相关产品推荐
相关产品推荐

