You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中jsonDecode返回String而非List的问题及两次解码生效原因

JSON解码两次才得到List的原因分析

问题背景

想要把目标JSON解码成List,但Flutter的jsonDecode方法第一次返回的是String类型而非List,直接转List会失败,连续调用两次jsonDecode(jsonDecode(response.body))却能成功得到List。

目标JSON数据

[{"TicketID":31,"EmpID":"11553","Name":"Test","Location":null,"PhoneExt":345345,"Code":null,"Reason":null,"Category":null,"Created":null,"Username":"abc","OtherLocation":null,"Room":null,"Floor":null,"CodeBlueDone":null,"CodeBlueDoneDate":null,"LocationCode":null,"PatientType":null,"EmergencyType":"Emergency","FilledDateTime":null,"SubmitDateTime":null,"Type":null,"CallTime":"2022-08-26T13:43:25.003","Status":"New"},{"TicketID":30,"EmpID":"12","Name":"dbdb","Location":null,"PhoneExt":123,"Code":null,"Reason":null,"Category":null,"Created":null,"Username":"abc","OtherLocation":null,"Room":null,"Floor":null,"CodeBlueDone":null,"CodeBlueDoneDate":null,"LocationCode":null,"PatientType":null,"EmergencyType":"Emergency","FilledDateTime":null,"SubmitDateTime":null,"Type":null,"CallTime":"2022-08-25T21:14:39.807","Status":"New"}]

解码相关代码

首次解码打印类型的代码:

if (response.statusCode == 200) {
  jsonDecode(response.body);
  print(jsonDecode(response.body).runtimeType);
}

异步获取数据的代码:

Future<List> _getDataFromWeb() async {
  try {
    await http.post(
      Uri.parse(apiURL),
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      },
    ).then((response) {
      if (response.statusCode == 200) {
        try {
          final resp = jsonDecode(response.body) as List?;
          print(resp.runtimeType);
        } catch (ex) {
          print("_getDataFromWeb() error: ${ex}");
        }
      } else if (response.statusCode == 404) {
        print("Error 404: ${response.statusCode}");
      } else {
        print("Error: ${response.statusCode}");
      }
    }).catchError((error) {
      print("Error: " + error);
    });
  } catch (ex) {
    print("API-ERR: $ex");
  }
}

原因分析

核心问题是接口返回的JSON数据被双重编码了:

  • 第一次调用jsonDecode(response.body)时,解码出来的是一个字符串——这个字符串本身就是你贴出来的那串JSON数组内容。
  • 第二次调用jsonDecode时,是把这个字符串形式的JSON再次解码,才得到了真正的List对象。

出现这种情况的本质是后端接口在返回数据时,先把数组序列化成JSON字符串,然后又把这个字符串再次做了一次JSON序列化,导致最终返回给前端的是一个被包裹的字符串类型JSON。比如正常应该返回[{"key":value},...],实际返回的却是"[{\"key\":value},...]"——外层多了引号,内部引号被转义,所以第一次解码只能拿到字符串,第二次解码才能解析成List。

验证与解决

  • 验证方式:直接打印response.body的原始内容,你会发现它是被引号包裹、内部字符转义的字符串,而非直接的JSON数组。
  • 解决办法:
    • 优先要求后端修复接口,确保只做一次JSON序列化,直接返回数组类型的JSON,这是最规范的解决方案。
    • 如果后端暂时无法修改,前端可以先解码一次得到字符串,再解码第二次得到List,但这只是临时 workaround,不推荐长期使用。

内容的提问来源于stack exchange,提问作者Bassam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:15:39