错误状态:无法设置内容类型为“application/json”的请求的正文字段
Posted
技术标签:
【中文标题】错误状态:无法设置内容类型为“application/json”的请求的正文字段【英文标题】:Bad state: Cannot set the body fields of a Request with content-type "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",
);
当我执行此操作时,我无法接收数据并且抛出的错误是
【问题讨论】:
试试 -body: json.encode("grant_type":"password","username":"******","password":"*****","scope":"offline_access"),
请注意,您还发布了您的username/password
,即使他们可能是测试用户,这不是一个好习惯...
【参考方案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<String, String>
作为正文传递,这显然会引发错误。
因此,要解决此问题,您需要将您的 Map<String, String>
数据更改(或 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);
【讨论】:
以上是关于错误状态:无法设置内容类型为“application/json”的请求的正文字段的主要内容,如果未能解决你的问题,请参考以下文章
JPQL:错误编译 - 状态字段“e.e2.e3”无法解析为有效类型
内容类型应用程序/soap+xml; charset=utf-8 不受服务支持