#flutter #http #flutter-http
#трепетание #http #трепетание-http
Вопрос:
Я изучаю третий пример http-пакета Flutter, это основа кода: https://pub.dev/packages/http
Когда запрос отправляется через BaseClient.send, немедленно будут отправлены только заголовки и все данные, которые уже были записаны в StreamedRequest.stream. Дополнительные данные будут отправлены, как только они будут записаны в StreamedRequest.sink, и когда приемник будет закрыт, запрос завершится.
https://pub.dev/documentation/http/latest/http/StreamedRequest-class.html
-
Из документов я не понимаю, как мы должны писать
StreamedRequest.stream
? (Для немедленной отправки данных) -
Не является StreamedResponse .sink в основном там, где мы добавляем тело запроса нашего HTTP POST: почему он принимает только a
List<int>
? Разве это не должно быть aMap<String, String>
? Если это не так, то куда мы должны добавить тело запроса?NEW:
Даже когда я кодирую его с помощью ut8.encode, он по-прежнему не отображается в веб-формах Fiddler при отладке, как мне правильно отправить x-www-form-urlencoded?:
Код:
userAgentClient = UserAgentClient(userAgent, client);
streamedRequest = http.StreamedRequest('POST', Uri(scheme: 'http', path: '/posts/', host: 'jsonplaceholder.typicode.com'));
streamedRequest.sink.add([123, 456]); // It has to be a List<int>
//NEW:
streamedRequest.sink.add(utf8.encode('username=123amp;password=456'));
streamedRequest.sink.add(utf8.encode('{"username":"123","password":"456"}'));
- Почему я должен закрывать приемник, чтобы иметь доступ к свойствам StreamedResponse?
streamedRequest.sink.close();
Обновить:
class UserAgentClient extends http.BaseClient {
final String userAgent;
final http.Client client;
UserAgentClient(this.userAgent, this.client);
Future<http.StreamedResponse> send(http.BaseRequest request){
request.headers['user-agent'] = userAgent;
return client.send(request);
}
}
dynamic _status = '';
dynamic _body = '';
dynamic _headers = '';
String _reason = '';
http.Client client = http.Client();
String userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36';
UserAgentClient userAgentClient;
http.StreamedRequest streamedRequest;
void _httpStreamed(){
userAgentClient = UserAgentClient(userAgent, client);
streamedRequest = http.StreamedRequest('POST', Uri(scheme: 'http', path: '/posts/', host: 'jsonplaceholder.typicode.com'));
streamedRequest.sink.add(utf8.encode('{"username":"123","password":"456"}'));
setState(() {
_status = streamedRequest.url;
_body = '';
_headers = '';
_reason = '';
});
}
void _httpSend() async{
http.StreamedResponse streamedResponse;
streamedResponse = await userAgentClient.send(streamedRequest);
streamedResponse.stream.listen(
(value) async{
_body = http.ByteStream.fromBytes(value);
_body = await _body.bytesToString();
},
onError: (e, sT) {
SnackBar sBar = SnackBar(content: Text('$en$sT',));
Scaffold.of(context).showSnackBar(sBar);
},
onDone: () {
SnackBar sBar = SnackBar(content: Text('Done lol'),);
Scaffold.of(context).showSnackBar(sBar);
},
);
setState(() {
_body;
_status = streamedResponse.statusCode;
_headers = streamedResponse.headers;
_reason = streamedResponse.reasonPhrase;
});
}
}
void _httpClose(){
if (streamedRequest != null){
streamedRequest.sink.close();
}
}
Итак, я запускаю первые 2 функции, но _body
переменная не отображается на моем экране, пока я не запущу _httpClose()
функцию.
Комментарии:
1. этот обновленный код, который вы создали, является полностью рабочей версией?
2. @CassioSeffrin Я изучаю Flutter, и я пытался полностью изучить пакет http Flutter, поэтому я создал приложение для тестирования всего, что в нем есть. Поскольку вы заинтересованы, я загрузил полностью рабочую версию здесь для вас: github.com/Saya47/Flutter-http-learning Весь код находится в одном файле dart, скопируйте и вставьте его в свой тестовый проект flutter, создайте приложение и протестируйте все!
3. Спасибо @Shayan. На данный момент мне нужно только проверить, сработал ли этот потоковый запрос. Я сделал это по-другому: окончательный запрос = запрос (‘GET’, Uri.parse(url)); request.headers.addAll(заголовки); окончательный ответ StreamedResponse = ожидание клиента ().отправить (запрос); Дополнительно мне нужно настроить тайм-аут, но Client().у отправки нет аргументов, необходимых для этого.
Ответ №1:
-
ДА
-
Map<String,String>
не может быть потоковым. Потоковое означает, что данные отправляются порциями каждый раз, когда поток отправляет порцию данных, и сервер (или буфер отправки браузеров) готов к приему дополнительных данных.List<int>
может быть разделен на фрагменты, потому что не имеет значения, сколько байтов отправляется одновременно. Если у вас есть все доступные данные, вы, вероятно, не хотите использовать StreamedRequest, особенно если это не большой двоичный объект данных. https://en.wikipedia.org/wiki/Binary_large_object
utf8.encode
может использоваться для кодирования фрагментов, передаваемых потоком, но сам по себе поток не создается, поэтому вы не можете добавить результат utf8.encode
в приемник.
- Я не понимаю этого вопроса. К каким свойствам doe вы хотите получить доступ и с какими проблемами вы сталкиваетесь при попытке?
Для меня не похоже, что вам не нужно использовать StreamedRequest для вашего варианта использования.
Комментарии:
1. Большое спасибо, теперь все имеет смысл, для 3, в основном, когда я хочу проверить ответ сервера, например, тело, оно не отображается, пока я не закрою приемник, я обновлю свой код через минуту.
2. Хорошо, это невозможно, потому что запрос не может быть завершен до закрытия потока (сигнализируется, что больше не будет данных), и вы не можете получить доступ к ответу до запроса, очевидно;-)