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

Flutter POST请求触发Format Exception异常及CSRF相关疑问

解决Flutter POST请求的FormatException问题 & CSRF Token疑问

嘿,我来帮你一步步梳理问题、解决这个报错:

一、错误根源拆解

从错误日志能直接看到:你尝试解析的响应是HTML页面(<!DOCTYPE html>)而非预期的JSON,这说明你的POST请求触发了服务器错误(比如404、400、403),返回了错误页面而非正常JSON。结合你的代码,有几个核心问题:

  1. 手动拼接JSON易出错:比如"userid": $id,如果id是字符串类型,这里会直接裸拼值,没加引号,导致JSON格式无效,服务器无法识别后返回错误页面。
  2. 缺少关键请求头:没设置Content-Type: application/json,服务器可能无法识别请求体是JSON格式,直接返回错误。
  3. 位置信息赋值逻辑错误:updateLocation里你先给longitude/latitude赋值_position的属性,但此时_position还没初始化,会导致这两个值为null,传到POST请求里引发后续问题。

二、代码修复步骤

1. 修复位置信息赋值逻辑

修改updateLocation,确保用刚获取到的位置数据赋值:

void updateLocation() async {
  try {
    Position newPosition = await Geolocator()
        .getCurrentPosition(desiredAccuracy: LocationAccuracy.high)
        .timeout(const Duration(seconds: 5));
    // 改用新获取的位置数据赋值
    longitude = newPosition.longitude;
    latitude = newPosition.latitude;
    setState(() {
      _position = newPosition;
    });
  } catch (e) {
    print('Error: ${e.toString()}');
  }
}

2. 重构POST请求写法

放弃手动拼接JSON,用json.encode生成标准JSON字符串,并添加必要请求头:

import 'dart:convert'; // 确保导入这个包

Future<Map<String, dynamic>> sendRequestWithPost(
    String id, String desc, double lat, double lon) async {
  var client = http.Client();
  Map<String, dynamic> requestBody = {
    "userid": id,
    "latitude": lat,
    "longitude": lon,
    "description": desc
  };
  print("id: $id Desc: $desc lat: $lat lon: $lon");
  String url = "你的POST请求实际URL"; // 替换成真实接口地址
  try {
    final response = await client.post(
      Uri.parse(url), // 用Uri.parse替代Uri.encodeFull更安全
      headers: {
        'Content-Type': 'application/json', // 必须添加这个头,告诉服务器请求体是JSON
      },
      body: json.encode(requestBody), // 自动生成标准JSON,避免手动拼接错误
    ).whenComplete(client.close);

    // 先检查响应状态码,确认请求成功再解析
    if (response.statusCode == 200) {
      if (!mounted) {
        return {'success': false};
      }
      final res = json.decode(response.body);
      print(res);
      setState(() {}); // 不需要更新UI的话可以去掉这行
      return res;
    } else {
      // 打印错误信息方便排查
      print('请求失败,状态码: ${response.statusCode}');
      print('服务器返回内容: ${response.body}');
      return {'success': false, 'error': '服务器错误'};
    }
  } catch (e) {
    print('请求异常: ${e.toString()}');
    return {'success': false, 'error': e.toString()};
  }
}

3. 额外排查点

  • 先在Postman等工具里测试你的POST接口,确认能正常返回JSON
  • 如果是本地调试,检查服务器是否配置了CORS跨域允许(否则Flutter本地请求会被拦截)

三、关于CSRF Token的疑问

  • 如果你的REST端点没有启用CSRF验证,完全不需要处理CSRF Token,代码可以正常运行。
  • 如果端点启用了CSRF验证,通常需要:
    1. 从服务器Cookie中获取XSRF-TOKEN(多数后端框架会自动设置这个Cookie)
    2. 在POST请求头里添加X-XSRF-TOKEN,值为获取到的Token
      不过从当前错误来看,你的问题和CSRF无关,先解决前面的请求格式问题即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:15:56