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

Dart中http库POST请求返回400且未达服务器的正确写法咨询

解决Dart http库POST请求返回400的问题

这种400错误我之前踩过好几次,大多是请求格式和服务器预期不匹配导致的——毕竟Postman能成功,说明服务器逻辑没问题,问题肯定出在Dart代码的请求构造上。我给你梳理下常见坑点和正确的写法:

最常见的错误原因

  • Content-Type未设置或设置错误:服务器如果期望接收JSON格式,你没加Content-Type: application/json头,它根本不知道怎么解析请求体
  • 请求体未正确序列化:直接把Map传给body,http库会默认转成form-urlencoded格式,和Postman里的JSON格式完全不一样
  • 字段不匹配:比如服务器需要product_name但你传了name,或者字段大小写不对(很多服务器区分大小写)
  • 缺少必要请求头:比如服务器要求的认证Token、Accept头你没加

正确的JSON格式POST请求代码

先确保你在pubspec.yaml里加了http依赖:

dependencies:
  http: ^1.1.0

然后是核心代码,完全对齐Postman的请求格式:

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

Future<void> addProduct() async {
  // 注意URL要和Postman里完全一致,别写错端口或路径
  final apiUrl = Uri.parse('http://localhost:8000/api/products/');

  // 构造和Postman里完全一样的请求体数据
  final productPayload = {
    'name': 'Sample Product',
    'price': 29.99,
    'description': 'A test product from Dart',
    // 其他服务器要求的字段,比如category_id,一定要和Postman里的键名、类型一致
  };

  try {
    final response = await http.post(
      apiUrl,
      headers: {
        // 必须加这个!告诉服务器我们发的是JSON
        'Content-Type': 'application/json',
        // 如果Postman里有Authorization头(比如Bearer Token),一定要同步加上
        // 'Authorization': 'Bearer your_auth_token_here',
      },
      // 关键:用jsonEncode把Map转成JSON字符串,而不是直接传Map
      body: jsonEncode(productPayload),
    );

    if (response.statusCode == 201) {
      print('Product created successfully!');
      print('Server response: ${response.body}');
    } else {
      // 打印服务器返回的错误信息,这是排查关键!比如服务器会说"缺少name字段"
      print('Request failed with status ${response.statusCode}');
      print('Error details: ${response.body}');
    }
  } catch (e) {
    print('Network error occurred: $e');
  }
}

排查步骤帮你定位问题

  1. 对比请求细节:用print把你的请求头、请求体打出来,和Postman的请求详情(Postman里点"Code"按钮能看到原始请求)对比,找差异
  2. 看服务器日志:直接去本地服务器的日志里看,服务器通常会明确告诉你为什么返回400(比如JSON格式错误、缺少必填字段)
  3. 验证URL和端口:确保你的Dart代码里的URL和Postman里完全一致,别把localhost写成localhos,8000写成8080

如果服务器接受Form-Data格式

如果你的Postman用的是Form-Data而不是Raw JSON,那代码要改成Multipart请求:

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

Future<void> addProductFormData() async {
  final apiUrl = Uri.parse('http://localhost:8000/api/products/');
  final request = http.MultipartRequest('POST', apiUrl);

  // 添加表单字段,数值要转成字符串
  request.fields['name'] = 'Sample Product';
  request.fields['price'] = '29.99';

  // 如果需要上传文件,加上这段
  // request.files.add(await http.MultipartFile.fromPath(
  //   'image',
  //   'path/to/your/image.jpg',
  // ));

  final response = await http.Response.fromStream(await request.send());

  if (response.statusCode == 201) {
    print('Product created!');
  } else {
    print('Failed: ${response.statusCode} - ${response.body}');
  }
}

按照这个写法调整后,应该就能和Postman一样拿到201响应了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:40:34