在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
相关产品推荐
相关产品推荐

