Http POST 在 Postman 中有效,但在 Flutter 中无效

问题描述 投票:0回答:3

我正在尝试使用 Http 包对我的 flutter 应用程序执行 POST 请求。我首先在 Api 沙盒网站上测试了我的请求,然后在 Postman 中测试了我的请求。它在那里工作得很好,但是一旦进入 Flutter,我总是收到 400 Bad Request。

这是我在 Flutter 中的代码:

import 'package:http/http.dart';
import 'package:uuid/uuid.dart';
import 'package:wave_app/env/secrets.dart';
import 'package:wave_app/models/momo_token.dart';

    String url = "https://sandbox.momodeveloper.mtn.com/collection/v1_0/requesttopay";
    var uuid = Uuid();
    String requestId = uuid.v4();
    MomoToken token = await _createMomoNewTokenCollection();

    String auth = "Bearer " + token.accessToken;

    Map<String, String> headers = {
      "Authorization": auth,
      "X-Target-Environment": "sandbox",
      "X-Reference-Id": requestId,
      "Content-Type": "application/json",
      "Ocp-Apim-Subscription-Key": momoCollectionSubscriptionKey
    };

    String jsonBody = '{"amount": "5","currency": "EUR", "externalId": "123", "payer": {"partyIdType": "MSISDN","partyId": "46733123454"}, "payerMessage": "tripId-123456","payeeNote": "driverId-654321"}';

    Response response = await post(url, headers: headers, body: jsonBody);
    int statusCode = response.statusCode;

    print("STATUS CODE REQUEST TO PAY " + statusCode.toString());
    print(response.reasonPhrase.toString());
    print(response.body.toString());

    if (statusCode == 202) {
      return response.body.toString();
    } else {
      return null;
    }
  }

API 文档在这里:https://momodeveloper.mtn.com/docs/services/collection/operations/requesttopay-POST?

这是我的 Postman 请求的curl 中的代码(使用上面 requestId、auth、momoCollectionSubscriptionKey 相同的变量)

curl --request POST \
  --url https://sandbox.momodeveloper.mtn.com/collection/v1_0/requesttopay \
  --header 'Accept: */*' \
  --header 'Accept-Encoding: gzip, deflate' \
  --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6IjFmY2MzMjBhLTM0NWQtMTFlYS04NTBkLTJlNzI4Y2U4ODEyNSIsImV4cGlyZXMiOiIyMDIwLTAxLTExVDE1OjU3OjE4Ljc3NyIsInNlc3Npb25JZCI6ImZmYzc1OGE2LTM2MWEtNDM4ZS1hYjE5LWQ1ZGQ4ZmU4ZjEyOSJ9.DeoJyU6Hb0he_or1XeBxW-6s-xwdtmi0cUrYjQe0Z796bIGvvT-VJ214JaZItG-CBQpgv7dHbLfXNqr8D05Q7U9XiOtpr8mtYWQlY-MseGIHAyxp1qBuQkwjmBYBlDxQOYYfzG9SZ8tGFUI1_k59LMNYIhDlXXKa68Ym1sylZ8wfWjGuHaKVzMEH25ubiBwCLev5IHPchuF3toVP99U-HC8t95E3zrEt9dHgzn0hnwvpB31wcsu_b3vb-YZ1idHgosPc2GmKFsDruX14VniKBicCsnGHqZAkSPXwaOR6SIn4JZEEwhAIj3Oe2H5dwxloiX5rzaApdkwEg6KSoBXk8A' \
  --header 'Cache-Control: no-cache' \
  --header 'Connection: keep-alive' \
  --header 'Content-Length: 194' \
  --header 'Content-Type: application/json' \
  --header 'Host: sandbox.momodeveloper.mtn.com' \
  --header 'Ocp-Apim-Subscription-Key: 281eb****************' \
  --header 'Postman-Token: ece19062-1f0b-4873-a3ed-1bd4ada8746a,528004b2-410d-4653-9909-5197a3dc95db' \
  --header 'User-Agent: PostmanRuntime/7.20.1' \
  --header 'X-Reference-Id: 062f8aad-f529-4d0a-804c-affb888c2b8b' \
  --header 'X-Target-Environment: sandbox' \
  --header 'cache-control: no-cache' \
  --data '{\r\n  "amount": "5",\r\n  "currency": "EUR",\r\n  "externalId": "123",\r\n  "payer": {\r\n    "partyIdType": "MSISDN",\r\n    "partyId": "46733123454"\r\n  },\r\n  "payerMessage": "hi",\r\n  "payeeNote": "hi"\r\n}'

在邮递员及其网站上,我总是收到 202 Accepted 回复。 我不确定我在这里做错了什么。任何帮助将不胜感激!

------------编辑--------------------------------

我也尝试过使用 HttpClient,这是代码,但仍然收到 400 Bad Request

HttpClient httpClient = new HttpClient();
    HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));

    request.headers.set("Authorization", "Bearer " + token.accessToken);
    request.headers.set('content-type', 'application/json');
    request.headers.set("X-Target-Environment", "sandbox");
    request.headers.set("X-Reference-Id", requestId);
    request.headers.set("Ocp-Apim-Subscription-Key", momoCollectionSubscriptionKey);

    request.add(utf8.encode(jsonBody));
    HttpClientResponse response = await request.close();

    print("STATUS CODE " + response.statusCode.toString() + "   " + response.reasonPhrase);
    String reply = await response.transform(utf8.decoder).join();
    print("REPLY " + reply);
    httpClient.close();

flutter http post postman
3个回答
6
投票

这肯定是服务器的问题。服务器正在区分大小写地处理两个标头

X-Reference-Id
X-Target-Environment
(即,它不符合 RFC)。

Dart 的

io.HttpClient
强制标题小写,因此这会影响
package:http
package:dio
,它们都依赖它。有一个请求允许客户端保留标头的大小写,但它进展缓慢,因为这是一个重大更改。

同时,尝试使用客户端的这个分支来保留标头大小写。 https://pub.dev/packages/alt_http/


1
投票

我通过添加此标题解决了我的问题:

'content-type': 'multipart/form-data'

0
投票

通过将 jsonBody 从 String 更改为 Map 解决了同样的问题。

 String jsonBody = '{"amount": "5","currency": "EUR", "externalId": "123", "payer": {"partyIdType": "MSISDN","partyId": "46733123454"}, "payerMessage": "tripId-123456","payeeNote": "driverId-654321"}';

仅当 从 String -> Map 更改时解决;

 Map jsonBody = {"amount": "5","currency": "EUR", "externalId": "123", "payer": {"partyIdType": "MSISDN","partyId": "46733123454"}, "payerMessage": "tripId-123456","payeeNote": "driverId-654321"};

此外,还包括 jsonEncode

响应response =等待post(url, headers: headers, body: jsonEncode(jsonBody));

jsonEncode 需要导入 Convert 库

import 'dart:convert';
© www.soinside.com 2019 - 2024. All rights reserved.