Как сделать запрос HTTP POST с закодированным текстом теле в флаттер?
Я пытаюсь сделать запрос на отправку с типом контента с кодировкой url. Когда я пишу body: json.encode(data)
, он кодируется в обычный текст.
Если я пишу body: data
я получаю type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'String' in type cast
ошибки 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"));
Ответы
Ответ 1
Вам нужно добавить три дополнительных шага: сначала вам нужно преобразовать json-карту в String (используя json.encode). Затем вам нужно закодировать Uri, если вы хотите отправить его как application/x-www-form-urlencoded. Наконец, вам нужно указать параметр, по которому вы отправляете имя.
Например (обратите внимание, что это использование дротика: 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 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();
}
Вышесказанное относится к дроти: версия io (которую, конечно же, можно использовать в Flutter). Если вы хотите придерживаться пакета: http-версия, то вам нужно немного настроить карту. Тело должно быть Map <String, String>. Вам нужно решить, что вы хотите в качестве параметров 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 + А% 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 + А% 22% 7D% 2C% 22awayTeam% 22% 3A% 7B% 22team% 22% 3A% 22Team + В % 22% 7D% 7D
пакет: клиент http заботится: кодирование Uri.encodeQueryComponent, кодировка utf8 (обратите внимание, что это значение по умолчанию, поэтому нет необходимости указывать его) и отправки длины в заголовке Content-Length. Вы все равно должны выполнить кодировку json.
Ответ 2
Я бы хотел порекомендовать вам пакет dio, dio - мощный Http-клиент для Dart/Flutter, который поддерживает перехватчики, 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 может автоматически кодировать данные.
Более подробная информация, пожалуйста, обратитесь к дио.
Ответ 3
вам нужно использовать 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"));
Ответ 4
Код ниже - это функция, которую я создал для отправки запроса 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,
);
Ответ 5
Я пришел сюда, просто пытаясь сделать 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;
}