Flutter对接XAMPP phpMyAdmin提交发票报FormatException异常
问题根因
你碰到的FormatException: Unexpected character (at character 1) <br /> ^异常,本质是后端PHP返回了HTML格式的错误片段——XAMPP默认开启前端错误显示,PHP代码运行报错时会直接输出以<br />开头的HTML错误信息,而Flutter端的响应处理逻辑默认按JSON格式解析返回内容,碰到HTML标签就直接抛出格式错误。
核心触发点就是你排查到的序列化问题:调用json.encode时order_items数组内的订单项被转成了字符串,而非标准JSON对象。出现这个问题只有两种可能:
- OrderItem模型没有编写正确的
toJson()方法,序列化时直接触发对象的toString(),把结构化数据转成了转义字符串 - 组装PurchaseInvoice对象时,你提前对每个OrderItem做了
json.encode,把转完的JSON字符串塞进了order_items列表
后端拿到这种格式的请求时,主发票记录的插入逻辑不依赖order_items字段的解析,所以能正常入库;但循环插入商品行时,代码会把order_items里的元素当数组/对象处理(比如直接写$item['goods_id']取值),此时元素是字符串,PHP直接抛出类型错误,输出HTML报错内容,这也是为什么手动调用接口(手动传参时order_items是标准对象数组)完全正常,只有Flutter端提交会报错。
修复方案
- 修正模型序列化逻辑
检查两个模型的toJson()实现,确保OrderItem的toJson()直接返回Map<String, dynamic>结构,不要在任何环节对单个OrderItem提前做json.encode。正确写法参考:
必须避免这类错误写法:// 订单项模型正确实现 class OrderItem { final int goodsId; final num purchasePrice; final int quantity; OrderItem({required this.goodsId, required this.purchasePrice, required this.quantity}); // 直接返回Map,不要在这层做json.encode Map<String, dynamic> toJson() => { 'goods_id': goodsId, 'price': purchasePrice, 'num': quantity, }; } // 采购发票模型正确实现 class PurchaseInvoice { final String invoiceCode; final List<OrderItem> orderItems; // 其余发票字段略 PurchaseInvoice({required this.invoiceCode, required this.orderItems}); Map<String, dynamic> toJson() => { 'invoice_no': invoiceCode, // 直接传对象列表,json.encode会自动递归调用每个元素的toJson 'order_items': orderItems, }; }// 错误:提前把单个订单项转成字符串再塞列表 orderItemList.add(json.encode(currentItem.toJson())); - 校验序列化结果
序列化完成后打印请求体,确认order_items内的元素没有被双引号整体包裹、没有多余的转义斜杠,正确结构如下:{ "invoice_no": "CG202405001", "order_items": [ {"goods_id": 1, "price": 12.5, "num": 10}, {"goods_id": 3, "price": 8.0, "num": 20} ] } - 后端增加兜底逻辑(建议配置,避免后续同类问题直接抛HTML错误)
- 接口最开头加上
header('Content-Type: application/json');,强制所有响应走JSON格式 - 解析
order_items前增加类型判断,如果元素是字符串类型,先调用json_decode转成数组再处理 - 生产环境下修改php.ini配置,设置
display_errors = Off,PHP错误直接写入日志,不要向前端输出HTML错误片段
- 接口最开头加上
- 优化Flutter端请求异常捕获
HTTP请求方法里增加响应格式校验,如果返回内容不是合法JSON,先打印原始响应文本再抛异常,避免因为后端返回非JSON内容时看不到真实报错信息。
改完后重新提交即可正常插入全部数据,不会再触发格式解析异常。
内容的提问来源于stack exchange,提问作者smile675
相关产品推荐
相关产品推荐

