HttpClient în Dart

HTTP (dart:io) Dart 1.0

HttpClient trimite cereri HTTP și HTTPS din programele Dart de consolă și server; close îl închide la final.

Sintaxă
import 'dart:io';

HttpClient()
Duration? connectionTimeout
String? userAgent
void close({bool force = false})

Ce face HttpClient

HttpClient din dart:io este clientul HTTP inclus în Dart. O cerere are trei pași: o deschizi (getUrl, postUrl), o închizi cu await cerere.close(), care o trimite și returnează răspunsul (HttpClientResponse), apoi citești corpul răspunsului ca flux.

Un singur HttpClient poate trimite multe cereri și refolosește conexiunile deschise. Proprietăți utile: connectionTimeout (cât așteaptă conectarea), idleTimeout, userAgent.

La final apelezi client.close(): închide conexiunile libere, iar cererile în curs se termină normal. close(force: true) oprește și cererile în curs. Pentru aplicații mai mari se folosește des pachetul http, care are o interfață mai simplă și funcționează și pe web.

Exemple

Exemplul 1: O cerere GET către un server local

Programul pornește un mic server pe 127.0.0.1 (port ales de sistem) și îl apelează cu HttpClient.

import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
  server.listen((cerere) {
    cerere.response
      ..write('Bun venit pe serverul din Iași!')
      ..close();
  });

  final client = HttpClient();
  final cerere = await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'));
  final raspuns = await cerere.close();
  print('Status: ${raspuns.statusCode}');
  print('Corp: ${await raspuns.transform(utf8.decoder).join()}');

  client.close();
  await server.close();
}

Rezultat

Status: 200
Corp: Bun venit pe serverul din Iași!

Exemplul 2: userAgent și timp limită

Serverul răspunde cu antetul User-Agent primit, ca să vezi ce a trimis clientul.

import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
  server.listen((cerere) {
    final agent = cerere.headers.value(HttpHeaders.userAgentHeader);
    cerere.response
      ..write('Te-ai prezentat ca: $agent')
      ..close();
  });

  final client = HttpClient()
    ..userAgent = 'CatalogScolar/1.0'
    ..connectionTimeout = const Duration(seconds: 5);
  final raspuns = await (await client.getUrl(Uri.parse('http://127.0.0.1:${server.port}/'))).close();
  print(await raspuns.transform(utf8.decoder).join());

  client.close();
  await server.close();
}

Rezultat

Te-ai prezentat ca: CatalogScolar/1.0

Exemplul 3: Cerere către un site real

import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  final client = HttpClient();
  try {
    final cerere = await client.getUrl(Uri.parse('https://example.com/'));
    final raspuns = await cerere.close();
    final html = await raspuns.transform(utf8.decoder).join();
    print('Status: ${raspuns.statusCode}');
    print('Tip: ${raspuns.headers.contentType?.mimeType}');
    print(RegExp(r'<title>(.*)</title>').firstMatch(html)?.group(1));
  } on SocketException catch (eroare) {
    print('Fără conexiune: ${eroare.message}');
  } finally {
    client.close();
  }
}

Rezultat posibil (necesită internet)

Status: 200
Tip: text/html
Example Domain

Greșeli frecvente

  • Uiți await cerere.close(): cererea nu este trimisă și nu primești răspuns.
  • Nu citești corpul răspunsului: conexiunea rămâne ocupată și nu poate fi refolosită. Citește-l sau apelează raspuns.drain().
  • Nu apelezi client.close(): conexiunile rămase deschise țin programul de consolă pornit câteva secunde după ce a terminat.

Comenzi înrudite

  • HttpClient.getUrl: getUrl deschide o cerere GET (citire), postUrl o cerere POST (trimitere de date) spre adresa dată.
  • HttpServer: HttpServer.bind pornește un server web pe o adresă și un port; serverul este un flux de cereri (HttpRequest).
  • HttpRequest: HttpRequest este o cerere primită de HttpServer: metoda (GET, POST), adresa (uri), antetele, corpul și răspunsul de trimis.
  • jsonDecode: Citește un text JSON și îl transformă în Map, List, String, num, bool sau null; dă FormatException la text greșit.