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

在Flutter/Dart中如何发送带url编码头和体的HTTP POST请求

问题根因

你的代码触发400错误的核心原因是默认的application/x-www-form-urlencoded编码使用了Latin-1字符集,和服务端要求的UTF-8编码不匹配,特殊字符(比如redirect_uri里的符号、空格)转义后不符合服务端预期。

修复方案

1. http包版本

// 手动处理参数编码,避免http包默认的Latin-1编码逻辑
final params = {
  'grant_type': 'refresh_token',
  'refresh_token': refreshToken,
  'redirect_uri': redirectUri,
};
// 逐个对key、value做UTF-8编码的URL转义
final encodedBody = params.entries.map((entry) => 
  '${Uri.encodeComponent(entry.key, encoding: utf8)}=${Uri.encodeComponent(entry.value, encoding: utf8)}'
).join('&');

final response = await post(
  Uri.parse(URL),
  headers: {
    'Authorization': 'Basic ${base64Encode(utf8.encode('$ID:$SECRET'))}',
    // 明确指定编码格式
    'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
  },
  body: encodedBody,
);

2. Dio包版本

final dio = Dio.Dio();
// 开启日志可直接对比请求内容和curl的差异
// dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true));

final params = {
  'grant_type': 'refresh_token',
  'refresh_token': refreshToken,
  'redirect_uri': redirectUri,
};
final encodedBody = params.entries.map((entry) => 
  '${Uri.encodeComponent(entry.key, encoding: utf8)}=${Uri.encodeComponent(entry.value, encoding: utf8)}'
).join('&');

final response = await dio.post(
  URL,
  data: encodedBody,
  options: Dio.Options(
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    headers: {
      'Authorization': 'Basic ${base64Encode(utf8.encode('$ID:$SECRET'))}',
    },
  ),
);

调试建议

你可以在本地使用抓包工具(如Charles、mitmproxy)分别抓取curl成功请求和Flutter失败请求的内容,对比头信息、请求体的差异,可快速定位其他潜在问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:24:04