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

Flutter向Django POST请求报400错误:请求语法问题排查

排查Flutter POST请求到Django后端的400语法错误问题

我来帮你拆解这个问题,从错误日志到代码细节一步步排查:你用Postman向Django的/account/login/接口发POST请求完全正常,但用Flutter的HttpClient发送Map数据时,不仅出现了406错误,还触发了Bad request syntax ('32')的400错误,而且是在添加request.add(utf8.encode(json.encode(map)))之后出现的。

错误日志分析

先看Django的日志:

[19/May/2020 14:58:13] "POST /account/login/ HTTP/1.1" 406 42
[19/May/2020 14:58:13] code 400, message Bad request syntax ('32')
[19/May/2020 14:58:13] "32" 400 -

  • 406错误对应你Django代码里的参数缺失分支(wrong parameter),说明最初请求的参数没有被Django正确解析
  • 后面的400错误(Bad request syntax ('32'))更关键,这表示Django接收到了格式完全错误的请求内容,甚至不是一个合法的HTTP请求,看起来像是只收到了字符32

问题根源

问题出在Flutter的HttpClient使用方式上:

  1. 当你用request.add()添加请求体时,可能没有正确结束请求体的写入,或者HttpClient没有自动帮你设置Content-Length头,导致Django端接收请求时出现解析异常
  2. 另外,你在函数里硬编码了map = { "username":"user", "password":"password" };,这会覆盖传入的data参数,这也是一个小问题(不过和当前错误无关,但需要修正)

解决步骤和代码修正

针对HttpClient的请求问题,我们可以做以下调整:

1. 正确设置请求头并确保请求体完整发送

手动计算并设置Content-Length头,同时改用request.write()或者确保add()之后正确关闭请求体写入:

修正后的Flutter代码:

import 'dart:convert';
import 'dart:io';

Future<dynamic> postGoa(String endpoint, Map data) async {
  // 注意:这里应该使用传入的data,而不是硬编码的map
  Map map = data; 
  var url = _getUrl("POST", endpoint);
  var client = HttpClient();
  
  try {
    HttpClientRequest request = await client.postUrl(Uri.parse(url));
    // 设置Content-Type为application/json
    request.headers.set(HttpHeaders.contentTypeHeader, 'application/json; charset=utf-8');
    if (athenticated != null && athenticated.isNotEmpty) {
      request.headers.set(HttpHeaders.authorizationHeader, 'Bearer ' + athenticated);
    }
    
    // 编码JSON数据
    String jsonBody = json.encode(map);
    // 计算内容长度并设置
    request.headers.set(HttpHeaders.contentLengthHeader, utf8.encode(jsonBody).length);
    // 写入请求体
    await request.write(jsonBody);
    
    HttpClientResponse response = await request.close();
    String mydata = await response.transform(utf8.decoder).join();
    return mydata;
  } catch (e) {
    // 捕获异常,方便调试
    print('请求异常:$e');
    return null;
  } finally {
    client.close();
  }
}

2. 更简洁的替代方案(推荐)

如果还是有问题,可以尝试用官方推荐的http包替代HttpClient,代码会更简洁,出错概率更低:

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<dynamic> postGoa(String endpoint, Map data) async {
  var url = Uri.parse(_getUrl("POST", endpoint));
  var headers = {
    'Content-Type': 'application/json',
    if (athenticated != null && athenticated.isNotEmpty)
      'Authorization': 'Bearer ' + athenticated,
  };
  var response = await http.post(url, headers: headers, body: json.encode(data));
  return response.body;
}

3. Django端调试优化

虽然Django代码本身没问题,但可以加个日志打印request.body,方便调试时查看Flutter发送的原始请求内容:

@api_view(['POST'])
def login_user(request):
    print("原始请求体:", request.body) # 添加这行调试代码
    print(request.data)
    # 后续代码不变...

这样你就能看到Flutter发送的内容到底是什么,更容易定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 18:33:09