我正在尝试使用内容类型作为网址编码来发布帖子请求。当我写body : json.encode(data)
时,它编码为纯文本。
如果我写body: data
,我会收到错误type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in type cast
这是数据对象
var match = {
"homeTeam": {"team": "Team A"},
"awayTeam": {"team": "Team B"}
};
我的要求
var response = await post(Uri.parse(url),
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
},
body: match,
encoding: Encoding.getByName("utf-8"));
答案 0 :(得分:14)
您需要添加三个额外步骤: 首先,您需要将json映射转换为String(使用json.encode) 然后,如果要将其作为application / x-www-form-urlencoded发送,则需要对其进行Uri编码。 最后,您需要提供要发布名称的参数。
例如(注意,这是使用dart:io HttpClient,但它基本相同):
Future<HttpClientResponse> foo() async {
Map<String, dynamic> jsonMap = {
'homeTeam': {'team': 'Team A'},
'awayTeam': {'team': 'Team B'},
};
String jsonString = json.encode(jsonMap); // encode map to json
String paramName = 'param'; // give the post param a name
String formBody = paramName + '=' + Uri.encodeQueryComponent(jsonString);
List<int> bodyBytes = utf8.encode(formBody); // utf8 encode
HttpClientRequest request =
await _httpClient.post(_host, _port, '/a/b/c');
// it's polite to send the body length to the server
request.headers.set('Content-Length', bodyBytes.length.toString());
// todo add other headers here
request.add(bodyBytes);
return await request.close();
}
以上是针对dart:io版本(当然,你可以在Flutter中使用) 如果您想坚持使用该软件包:http版本,那么您需要稍微调整一下Map。 body必须是Map&lt; String,String&gt;。您需要确定您想要的POST参数。你想要两个:homeTeam和awayTeam?或者一个,比如,teamJson?
此代码
Map<String, String> body = {
'name': 'doodle',
'color': 'blue',
'homeTeam': json.encode(
{'team': 'Team A'},
),
'awayTeam': json.encode(
{'team': 'Team B'},
),
};
Response r = await post(
url,
body: body,
);
在线上产生
名=涂鸦&安培;颜色=蓝色&安培; homeTeam =%7B%22team%22%3A%22Team + A%22%7D&安培; awayTeam =%7B%22team%22%3A%22Team + B%22%7D
或者,这个
Map<String, String> body = {
'name': 'doodle',
'color': 'blue',
'teamJson': json.encode({
'homeTeam': {'team': 'Team A'},
'awayTeam': {'team': 'Team B'},
}),
};
Response r = await post(
url,
body: body,
);
在线上产生
名=涂鸦&安培;颜色=蓝色&安培; teamJson =%7B%22homeTeam%22%3A%7B%22team%22%3A%22Team + A%22%7D%2C%22awayTeam%22%3A%7B%22team% 22%3A%22Team + B%22%7D%7D
包:http客户端负责:编码Uri.encodeQueryComponent,utf8编码(请注意,这是默认值,因此无需指定)并在Content-Length标头中发送长度。您仍然必须执行json编码。
答案 1 :(得分:10)
我想向您推荐dio包,dio是Dart / Flutter的强大Http客户端,它支持拦截器,FormData,请求取消,文件下载,超时等。
dio非常易于使用,在您的情况下,您可以:
Map<String, String> body = {
'name': 'doodle',
'color': 'blue',
'teamJson': {
'homeTeam': {'team': 'Team A'},
'awayTeam': {'team': 'Team B'},
},
};
dio.post("/info",data:body, options:
new Options(contentType:ContentType.parse("application/x-www-form-urlencoded")))
dio可以自动编码数据。
更多详情请参阅dio。
答案 2 :(得分:5)
您需要使用json.encode
示例;
var match = {
"homeTeam": {"team": "Team A"},
"awayTeam": {"team": "Team B"}
};
var response = await post(Uri.parse(url),
headers: {
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded"
},
body: json.encode(match),
encoding: Encoding.getByName("utf-8"));
答案 3 :(得分:1)
我建议使用Dio库。使用API可以提供很多支持。
具有最新的Dio版本。只需执行以下操作:
BaseOptions options = new BaseOptions(
baseUrl: "https://www.xx.com/api",
connectTimeout: 5000,
receiveTimeout: 3000,);
Dio dio = new Dio(options);
//
Map<String, String> params = Map();
params['username'] = '6388';
params['password'] = '123456';
//
response = await dio.post("/login", data: FormData.fromMap(params));
答案 4 :(得分:0)
我来到这里只是想发出HTTP POST请求。这是如何执行此操作的示例:
import 'dart:convert';
import 'package:http/http.dart';
makePostRequest() async {
final uri = 'http://httpbin.org/post';
final headers = {'Content-Type': 'application/json'};
Map<String, dynamic> body = {'id': 21, 'name': 'bob'};
String jsonBody = json.encode(body);
final encoding = Encoding.getByName('utf-8');
Response response = await post(
uri,
headers: headers,
body: jsonBody,
encoding: encoding,
);
int statusCode = response.statusCode;
String responseBody = response.body;
}
答案 5 :(得分:0)
下面的代码是我创建的用于发送POST请求的功能
Future<http.Response> postData(String url, Map<String, dynamic> data) async {
Map<String, String> headers = await _getHeaders();
http.Response response = await http.post(
Uri.parse(kBaseUrl + url),
headers: headers,
body: data,
encoding: Encoding.getByName('utf-8'),
);
return response;
}
下面的代码是一个示例用法
Map<String, dynamic> authData = {
"email": "testsdsd",
"password": "sdsdsd",
};
// send an auth request to the API
http.Response response = await _networkService.postData(
'authenticate',
authData,
);
答案 6 :(得分:0)
我是用dart的http包做到这一点的。不太花哨。我的端点没有用其他方法接受参数,但是像这样接受了它们,并在参数中包含了括号。
import 'package:http/http.dart' as http;
String url = "<URL>";
Map<String, String> match = {
"homeTeam[team]": "Team A",
"awayTeam[team]": "Team B",
};
Map<String, String> headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
http.post(url, body: body, headers: headers).then((response){
print(response.toString());
});
答案 7 :(得分:0)
Map<String, String> body = {
'getDetails': 'true'
};
final response = await
http.post("https://example.com/", body: body);
if (response.statusCode == 200) {
//Your code
}
答案 8 :(得分:0)
在“ UserModel”位置输入模型名称,并且不要在主体中传递String,这将使用“ Map”产生问题,如下所示。
static Future<UserModel> performUserLogin(String username, String password) async{
try{
Map<String, String> headers = {"Content-type": "application/json"};
Map<String, String> JsonBody = {
'username': username,
'password': password
};
print("The JSON Object is here $body");
// make POST request
final response = await http.post(loginAPIURL,body: JsonBody);
// check the status code for the result
int statusCode = response.statusCode;
print("Login calling $response");
if (statusCode == 200){
}else{
return null;
//return UserModel();
throw Exception("Error in login");
}
} catch (e) {
throw Exception(e);
}
}
答案 9 :(得分:0)
使用 DIO 的简单获取请求:
Future<dynamic> get(String uri, {
Map<String, dynamic> queryParameters,
Options options,
}) async {
try {
var response = await _dio.get(
uri,
queryParameters: queryParameters,
options: options,
);
return response.data;
} on SocketException catch (e) {
throw SocketException(e.toString());
} on FormatException catch (_) {
throw FormatException("Unable to process the data");
} catch (e) {
throw e;
}
}
使用 DIO 的简单发布请求{您也可以发送文件和图像}:
Future<dynamic> post(
String uri, {
data,
Map<String, dynamic> queryParameters,
Options options,
}) async {
try {
var response = await _dio.post(
uri,
data: data,
queryParameters: queryParameters,
options: options,
);
return response.data;
} on FormatException catch (_) {
throw FormatException("Unable to process the data");
} catch (e) {
throw e;
}
}