在 dart 中执行 http post 的最佳方法是什么?

what is the best way of doing a http post in dart?

尝试发布此内容: {grant_type: 密码, 密码: 123456, 用户名: user1234} 用下面的代码

Future<HttpClientResponse> apiRequest(String url, String username, String password) async {
Map jsonMap = {'grant_type':'password','password':password,'username':username};
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
request.add(utf8.encode((jsonMap.toString())));
print((jsonMap.toString()));
return await request.close();
}

但回复说 {"error":"invalid_request","error_description":"The mandatory 'grant_type' parameter is missing."}

在邮递员身上尝试得到不同的结果

screen shot of response with postman

我认为没有最好的方法。目前我使用 Retrofit For Dart,这非常方便,因为它会生成实际的实现。

例如,

@POST('/oauth/token')
@Headers(Constant.HEADER)
Future<LoginResponse> loginByEmail(@Query("email") String email, 
@Query("password") String password, @Query("grant_type") String grantType);

会变成

@override
loginByEmail(email, password, grantType) async {
  ArgumentError.checkNotNull(email, 'email');
  ArgumentError.checkNotNull(password, 'password');
  ArgumentError.checkNotNull(grantType, 'grantType');
  const _extra = <String, dynamic>{};
  final queryParameters = <String, dynamic>{
    'email': email,
    'password': password,
    'grant_type': grantType
  };
  final _data = <String, dynamic>{};
  final Response<Map<String, dynamic>> _result = await _dio.request(
    '/oauth/token',
    queryParameters: queryParameters,
    options: RequestOptions(
        method: 'POST',
        headers: <String, dynamic>{

        },
        extra: _extra,
        baseUrl: baseUrl),
    data: _data);
  final value = LoginResponse.fromJson(_result.data);
  return Future.value(value);
}

好的,我不知道你用的是什么方法,但我会向你展示我的方法,它应该可以帮助你理解请求的结构。

服务器端代码显示:

POST - /api/getInfo

Request:

{
user_phone: ''
notes: ''
}

Response:

{
status: ''
}

所以这是服务器端代码,这个请求(一个 post 请求)需要一个变量 user_phone 和一个变量注释。它给了我们状态的响应。

因此,如果要对该服务器发出单个请求,我将执行以下操作:

String basicAuth = 'Basic ' + base64Encode(utf8.encode('$username:$password')); // <--- Generate the Basic Auth string
http.Response response = await http.get(
  'https://myRandomServer.com/api/getInfo',
  headers: <String, String>{'authorization': basicAuth}, // <--- Authorization in header
  body: {'user_phone': '5555555555', 'notes': 'Some note'}, // <--- Data required in body of request
);

if (response.body != null) {
  Map data = jsonDecode(responseStatus.body); // <--- Decoding from json file response
  myStatus = data.['status']; // <----  Piece of information I need
}

现在有比这更多的方法,但是,这应该可以帮助您找出原始代码可能有什么问题,或者需要如何修改它才能完成您想要做的事情。