Flutter HttpClient Post设置contentLength出现字节不匹配异常求助
解决"Content size exceeds specified contentLength"差1字节的问题
这个坑我踩过!大概率是你计算contentLength的方式错了——别直接用JSON字符串的length属性来设置,这是最常见的原因!
问题根源
Dart里String的length返回的是字符个数,但HTTP协议要求的contentLength是数据的UTF-8字节数。哪怕只是一个不起眼的隐形字符(比如换行符、空格),或者某些特殊字符的字节数和字符数不一致,都可能导致差1字节的情况。
正确的解决步骤
先编码成字节数组再取长度
先把数据转成JSON字符串,再编码成UTF-8字节数组,用数组的长度作为contentLength:Future<Map> ajaxPost(String serviceName, Map data) async { var responseBody = json.decode('{"data": "", "status": "NOK"}'); try { var httpClient = new HttpClient(); var uri = mid.serverHttps ? Uri.https(mid.serverUrl, yourPath) : Uri.http(mid.serverUrl, yourPath); // 关键步骤:先转JSON字符串,再转UTF-8字节 var jsonString = json.encode(data); var utf8Bytes = utf8.encode(jsonString); var request = await httpClient.postUrl(uri); request.headers.set('Content-Type', 'application/json'); // 用字节数组的长度设置contentLength request.contentLength = utf8Bytes.length; // 写入字节数组而不是字符串,避免编码差异 request.add(utf8Bytes); var response = await request.close(); // 后续处理逻辑... } catch (e) { // 异常处理 } return responseBody; }或者直接用更省心的http库
如果不是必须用HttpClient,可以用官方的http包,它会自动帮你计算contentLength,完全不用手动设置:import 'package:http/http.dart' as http; Future<Map> ajaxPost(String serviceName, Map data) async { var responseBody = json.decode('{"data": "", "status": "NOK"}'); try { var uri = mid.serverHttps ? Uri.https(mid.serverUrl, yourPath) : Uri.http(mid.serverUrl, yourPath); var response = await http.post( uri, body: json.encode(data), headers: {'Content-Type': 'application/json'}, ); if (response.statusCode == 200) { responseBody = json.decode(response.body); } } catch (e) { // 异常处理 } return responseBody; }排查隐形字符
如果还是有问题,可以打印出JSON字符串的长度和字节数组长度对比:print('字符串长度:${jsonString.length}'); print('字节长度:${utf8Bytes.length}');看看是不是差1,这时候可以检查JSON字符串末尾有没有不小心加的换行、空格,用
jsonString.trim()处理后再试试(不过json.encode生成的字符串一般不会有这种问题)。
内容的提问来源于stack exchange,提问作者boeledi
相关产品推荐
相关产品推荐

