Flutter POST请求触发Format Exception异常及CSRF相关疑问
解决Flutter POST请求的FormatException问题 & CSRF Token疑问
嘿,我来帮你一步步梳理问题、解决这个报错:
一、错误根源拆解
从错误日志能直接看到:你尝试解析的响应是HTML页面(<!DOCTYPE html>)而非预期的JSON,这说明你的POST请求触发了服务器错误(比如404、400、403),返回了错误页面而非正常JSON。结合你的代码,有几个核心问题:
- 手动拼接JSON易出错:比如
"userid": $id,如果id是字符串类型,这里会直接裸拼值,没加引号,导致JSON格式无效,服务器无法识别后返回错误页面。 - 缺少关键请求头:没设置
Content-Type: application/json,服务器可能无法识别请求体是JSON格式,直接返回错误。 - 位置信息赋值逻辑错误:
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验证,通常需要:
- 从服务器Cookie中获取
XSRF-TOKEN(多数后端框架会自动设置这个Cookie) - 在POST请求头里添加
X-XSRF-TOKEN,值为获取到的Token
不过从当前错误来看,你的问题和CSRF无关,先解决前面的请求格式问题即可。
- 从服务器Cookie中获取
内容的提问来源于stack exchange,提问作者jay jay
相关产品推荐
相关产品推荐

