【问题标题】:Bad state: Cannot set the body fields of a Request with content-type "application/json"错误状态:无法设置内容类型为“application/json”的请求的正文字段
【发布时间】:2019-07-17 21:13:25
【问题描述】:
Map<String,String> headers = {'Content-Type':'application/json','authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='};

var response = await post(Urls.getToken,
        headers: headers,
        body: {"grant_type":"password","username":"******","password":"*****","scope":"offline_access"},
      );

当我执行此操作时,我无法接收数据并且抛出的错误是

错误状态:无法设置内容类型为“application/json”的请求的正文字段

【问题讨论】:

  • 试试 - body: json.encode({"grant_type":"password","username":"******","password":"*****","scope":"offline_access"}),
  • 请注意,您还发布了您的username/password,即使他们可能是测试用户,这不是一个好习惯...

标签: http dart flutter


【解决方案1】:

你需要将body包裹在jsonEncode中。

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

Map<String,String> headers = {'Content-Type':'application/json','authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='};
final msg = jsonEncode({"grant_type":"password","username":"******","password":"*****","scope":"offline_access"});

var response = await post(Urls.getToken,
               headers: headers,
               body: msg,
            );

【讨论】:

  • 谢谢!起初我没有看到你的答案和问题之间的区别,但现在我看到关键是将地图文字包装在 jsonEncode
【解决方案2】:

jsonEncode包裹你的身体object

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

var headers = {
    'Content-Type':'application/json',
    'authorization':'Basic c3R1ZHlkb3RlOnN0dWR5ZG90ZTEyMw=='
};

final body = {
    'username':'foo',
    'password':'pass123'
}

var response = await post(
    Urls.getToken,
    headers: headers,
    body: jsonEncode(body), // use jsonEncode()
);

为什么是jsonEncode

body:可以是 HTML、JSON 或 XML 等。这意味着我们需要以特定格式发送/接收数据。您可以在content-type 标头中设置它,其默认值为text/plain

当您将content-type 标头设置为JSON 时,您必须将“有效”JSON 作为正文传递。但是您将Map&lt;String, String&gt; 作为正文传递,这显然会引发错误。

因此,要解决此问题,您需要将您的 Map&lt;String, String&gt; 数据更改(或 encode)为 JSON 数据。

最好的方法是使用jsonEncode 函数。

【讨论】:

    【解决方案3】:

    http 库有类似问题...更改为 dio 2.1.0 并且标头问题消失了。

    jsonEncode(body) 没有做到这一点,因为文档说:

    发送带有给定标头和正文的 HTTP POST 请求到给定的 URL,可以是 [Uri] 或 [String]。

    [body] 设置请求的正文。它可以是 [String]、[List] 或 [Map]。如果它是一个字符串,它是使用编码的 [编码] 并用作请求的正文。的内容类型 请求将默认为“text/plain”。

    如果 [body] 是一个 List,它被用作 请求。

    如果 [body] 是 Map,则使用 [encoding] 将其编码为表单字段。这 请求的内容类型将设置为 "application/x-www-form-urlencoded";这不能被覆盖。 [编码] 默认为 [utf8]。

    要对请求进行更细粒度的控制,请改用 [send]。

    Future<Response> post(url, {Map<String, String> headers, body, Encoding encoding});
    

    【讨论】:

      【解决方案4】:
      Map<String,String> header = {'Content-Type':'application/json-patch+json','accept':'application/json'};
          final msg = jsonEncode({"username":"$emailorPhoneN","password":"$passwrod"});
      
          try {
            var response = await http.post(UrlConstants.loginUrl, headers: header, body: msg,
            ).timeout(Duration(seconds: httpDuration));
            var convert = json.decode(response.body);
            print('**********Data from server $convert');
      
            if (convert == null) {
              return null;
            } else {
              String token = convert['token'];
      
              if (token != null) {
                SignUpModel signUpModel = SignUpModel.fromJson(convert);
                return signUpModel;
              } else {
                //*** GET Error message from the API provider.....
                SignUpModel signUpModel = SignUpModel.fromJson(convert);
                return signUpModel;
              }
            }
      

      【讨论】:

        【解决方案5】:

        异常是由于设置不正确的bodyFields引起的。 见:bodyFields

        bodyFields 用于 form-encoded 数据,而不是 JSON。 有关如何 POST JSON 的示例,请参阅:Write HTTP servers

        因此,您尝试将 Map 作为主体传递。在这种情况下,它会假设您实际上正在执行application/x-www-form-urlencoded。您需要做的是将Map 编码为字符串,然后执行您正在执行的操作。

        例子

          Future<http.Response> patchAPICall(
              String url, Map param, String token) async {
            var responseJson;
            try {
              final response = await http.patch(Uri.parse(url),
                  body: jsonEncode(param),
                  headers: {
                    "Authorization": token,
                    "Content-Type": "application/json"
                  }).timeout(const Duration(seconds: 60),
                  onTimeout: () => throw TimeoutException(
                      'The connection has timed out, Please try again!'));
              responseJson = response;
            } on SocketException {
              throw FetchDataException("You are not connected to internet");
            } on TimeoutException {
              print('Time out');
              throw TimeoutException("The connection has timed out, Please try again");
            }
            return responseJson;
          }
        

        【讨论】:

          【解决方案6】:

          对我来说,jsonencode(body) 不起作用。 这对我有用:

          body = json.encode(body);
          http.post(Uri.parse(uri), headers: header, body: body);
          

          【讨论】:

            猜你喜欢
            • 2020-04-05
            • 2020-08-10
            • 2015-05-29
            • 2019-08-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-16
            • 2012-02-28
            • 1970-01-01
            相关资源
            最近更新 更多