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

学习从JSONPlaceholder获取数据时遇错误,求技术协助

JSONPlaceholder异步请求数据错误排查

问题描述

我在学习从JSONPlaceholder获取异步请求数据的过程中遇到了错误,以下是相关的Web入口HTML代码及Flutter Dart实现代码,请帮忙排查问题:

Web入口HTML代码

<!--
  If you are serving your web app in a path other than the root, change the
  href value below to reflect the base path you are serving from.

  The path provided below has to start and end with a slash "/" in order for
  it to work correctly.

  For more details:
  * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

  This is a placeholder for base href that will be replaced by the value of
  the `--base-href` argument provided to `flutter build`.
-->
<base href="/">

<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">

<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="flutter_application_1">
<link rel="apple-touch-icon" href="icons/Icon-192.png">

<link rel="icon" type="image/png" href="favicon.png"/>

flutter_application_1
<link rel="manifest" href="manifest.json">

  // The value below is injected by flutter build, do not touch.
  var serviceWorkerVersion = null;

<script src="flutter.js" defer>

  window.addEventListener('load', function(ev) {
    // Download main.dart.js
    _flutter.loader.loadEntrypoint({
      serviceWorker: {
        serviceWorkerVersion: serviceWorkerVersion,
      }
    }).then(function(engineInitializer) {
      return engineInitializer.initializeEngine();
    }).then(function(appRunner) {
      return appRunner.runApp();
    });
  });

</script>

Flutter Dart实现代码

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart';

class JasonParsingSimple extends StatefulWidget {
  const JasonParsingSimple({super.key});

  @override
  State<JasonParsingSimple> createState() => _JasonParsingSimpleState();
}

class _JasonParsingSimpleState extends State<JasonParsingSimple> {
  @override
  void initState() {
    Future data;
    // TODO: implement initState
    super.initState();
    data = getData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Parsing Jason"),
      ),
      // body: Center(
      //     child: Container(
      //   child: FutureBuilder(
      //       future: getData(),
      //       builder: (context, AsyncSnapshot<dynamic> snapshot) {
      //         return Text(snapshot.data[0]['title']);
      //       }),
      // )),
    );
  }

  Future getData() async {
    var data;
    String url = "https://jsonplaceholder.typicode.com/posts";
    Network network = Network(url);

    data = network.fetchData();

    // data.then((value) {
    //   print(value[3]);
    // });

    return data;
  }
}

class Network {
  final String url;

  Network(this.url);

  Future fetchData() async {
    print("$url");

    Response response = await get(Uri.parse("url"));

    if (response.statusCode == 200) {
      print(json.encode(response.body));
      return json.encode(response.body);
    } else {
      print(response.statusCode);
    }
  }
}

错误排查与修复方案

1. 请求URL参数错误

Network类的fetchData方法中,传入Uri.parse("url")是把字符串"url"作为请求地址,而非类成员变量url,导致请求发送到无效地址。

修复:

Response response = await get(Uri.parse(url)); // 移除引号,使用类成员变量

2. JSON解析方向错误

当前用json.encode(response.body)将响应字符串再次编码为JSON字符串,实际需要将响应的JSON字符串解码为Dart对象(列表/Map),应使用json.decode。

修复:

if (response.statusCode == 200) {
  final decodedData = json.decode(response.body);
  print(decodedData);
  return decodedData;
}

3. FutureBuilder优化(注释代码启用建议)

如果要启用注释中的FutureBuilder,需注意:

  • 不要在build方法中直接调用getData(),否则每次组件重建都会发起新请求,应在initState中初始化并保存Future对象
  • 必须处理snapshot的不同状态(加载中、错误、空数据、成功),避免空指针异常

优化后的State类:

class _JasonParsingSimpleState extends State<JasonParsingSimple> {
  late Future<List<dynamic>> data;

  @override
  void initState() {
    super.initState();
    data = getData(); // 仅初始化一次
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("解析JSON"),
      ),
      body: Center(
        child: FutureBuilder<List<dynamic>>(
          future: data,
          builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return CircularProgressIndicator(); // 加载中显示转圈
            } else if (snapshot.hasError) {
              return Text("请求出错: ${snapshot.error}"); // 错误提示
            } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
              return Text("无数据"); // 空数据提示
            } else {
              return Text(snapshot.data![0]['title']); // 成功展示第一条数据的标题
            }
          },
        ),
      ),
    );
  }

  // getData方法保持修复后状态
}

4. 命名规范修正

类名JasonParsingSimple应为JsonParsingSimple(正确拼写JSON),虽不影响功能,但遵循规范更易维护。

修复后的完整Network类

class Network {
  final String url;

  Network(this.url);

  Future<List<dynamic>> fetchData() async {
    print("$url");

    Response response = await get(Uri.parse(url));

    if (response.statusCode == 200) {
      final decodedData = json.decode(response.body);
      print(decodedData);
      return decodedData;
    } else {
      print(response.statusCode);
      throw Exception("请求失败,状态码: ${response.statusCode}"); // 抛出异常供FutureBuilder捕获
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:25:18