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

Flutter中HTTP Post请求错误处理优化及代码改进咨询

你好!先解决你最头疼的HTTP请求超时和错误判断问题,再给你一些代码优化的建议,让你的应用更健壮、代码更好维护。

核心问题解决:可靠的请求状态判断与超时处理

你的代码目前只处理了服务器返回状态码的情况,但无网络、服务器不可达、请求超时这类场景会直接抛出异常,不会进入状态码判断逻辑,导致请求阻塞且无提示。我们可以通过「超时设置+异常捕获」的组合解决这个问题:

修改后的请求核心代码

new FlatButton(
  child: new Text("Send"),
  onPressed: () async {
    // 先关闭确认对话框
    Navigator.of(context).pop();
    // 显示加载提示,提升用户感知
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (ctx) => AlertDialog(title: Text("Sending...")),
    );

    Map<String, dynamic> newDados = {};
    newDados["usuario"] = _usuarioController.text.trim();
    newDados["placa"] = _placaController.text.trim();
    newDados["box"] = _boxController.text.trim();
    newDados["tipo_veiculo"] = dropdownValue1;
    _dadosList.add(newDados);

    final headers = {
      "Content-type": "application/json",
      "Accept": "application/json"
    };

    try {
      // 设置2秒超时,同时用Uri.parse规范URL拼接
      final resp = await http.post(
        Uri.parse('http://$ipServidor'),
        body: jsonEncode(_dadosList + _pecasList),
        headers: headers,
      ).timeout(const Duration(seconds: 2));

      print(resp.statusCode);
      _dadosList.clear();
      print(resp.body);

      // 关闭加载对话框
      Navigator.of(context).pop();

      // 处理服务器响应
      if (resp.statusCode == 200) {
        if (resp.body == "ok") {
          setState(() {
            _pecasList.clear();
            _placaController.clear();
            _boxController.clear();
            dropdownValue1 = "Vehicle type";
          });
          Toast.show("\n Sent successfully! \n", context,
              duration: Toast.LENGTH_LONG,
              gravity: Toast.CENTER,
              backgroundRadius: 5.0);
        } else {
          _showAlert(context, "Error", "Server returned unexpected response");
        }
      } else {
        _showAlert(context, "Communication Error", "Server error: ${resp.statusCode}");
      }
    } on TimeoutException {
      // 捕获超时异常
      Navigator.of(context).pop();
      _showAlert(context, "Timeout", "Request timed out, please try again");
    } on SocketException {
      // 捕获无网络/服务器不可达异常
      Navigator.of(context).pop();
      _showAlert(context, "Network Error", "No internet or server is unreachable");
    } catch (e) {
      // 捕获其他所有未知异常
      Navigator.of(context).pop();
      _showAlert(context, "Unexpected Error", "Something went wrong: ${e.toString()}");
    }
  },
),

// 通用弹窗工具函数,避免重复代码
void _showAlert(BuildContext context, String title, String content) {
  showDialog(
    context: context,
    builder: (ctx) => AlertDialog(
      title: Text(title),
      content: Text(content),
      actions: [
        FlatButton(
          child: const Text("Close"),
          onPressed: () => Navigator.of(ctx).pop(),
        ),
      ],
    ),
  );
}

关键改进点

  • 添加timeout设置,2秒未响应自动触发超时提示
  • 用try-catch精准捕获不同类型的异常,覆盖所有失败场景
  • 新增加载对话框,让用户明确知道请求正在进行
  • 用Uri.parse替代字符串拼接URL,避免格式错误
  • 提取通用弹窗函数,减少代码重复

其他代码优化建议

作为首个应用,你的代码能跑通已经很棒了,以下建议能让代码更易维护:

1. 拆分逻辑为独立函数

把输入验证、请求发送这类重复/复杂逻辑拆成单独函数,让主代码更简洁:

// 输入验证函数
bool _validateInputs() {
  if (_usuarioController.text.isEmpty || 
      _placaController.text.isEmpty || 
      _boxController.text.isEmpty || 
      dropdownValue1 == "Vehicle type") {
    Toast.show("\n Complete all fields \n", context,
        duration: Toast.LENGTH_LONG,
        gravity: Toast.CENTER,
        backgroundRadius: 5.0);
    return false;
  }
  if (_pecasList.isEmpty) {
    _showAlert(context, "Empty List", "Please add items first");
    return false;
  }
  return true;
}

2. 使用空安全语法

Dart现在推荐空安全,把Map()改成{}或Map<String, dynamic>(),避免潜在空指针问题。

3. 优化输入处理

用trim()替代trimLeft(),同时可以给输入框添加输入格式校验(比如车牌号格式),提前拦截无效输入。

4. 避免硬编码字符串

把提示文本、按钮文字抽成常量,方便后续修改和国际化:

const String kCompleteAllFields = "\n Complete all fields \n";
const String kEmptyListTitle = "Empty List";

5. 代码格式化

用VS Code的Ctrl+Shift+F(或Android Studio的Ctrl+Alt+L)自动格式化代码,让缩进、换行更规范,可读性大幅提升。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 19:07:47