Dart HttpClientResponse
最后修改于 2025 年 4 月 4 日
Dart 中的 HttpClientResponse
类表示 HTTP 请求的响应。它提供了对响应头、状态码和响应体的访问。
HttpClientResponse 是一个字节数据流,必须完全读取或取消。它是 Dart dart:io
库的一部分,用于服务器端应用程序。
基本定义
HttpClientResponse
是一个抽象类,它实现了 Stream<List<int>>。它提供了 HTTP 特定的响应信息和作为流的响应体。
关键属性包括 statusCode、headers、contentLength 和 compressionState。必须消耗响应体以正确释放系统资源。
基本 HTTP GET 请求
本示例展示了如何进行简单的 GET 请求并读取响应。
import 'dart:io'; import 'dart:convert'; Future<void> main() async { var client = HttpClient(); try { var request = await client.getUrl(Uri.parse('https://example.com')); var response = await request.close(); print('Status code: ${response.statusCode}'); print('Headers: ${response.headers}'); var body = await response.transform(utf8.decoder).join(); print('Body length: ${body.length}'); } finally { client.close(); } }
我们创建一个 HttpClient,发出一个 GET 请求,并处理响应。响应体被读取为 UTF-8 字符串。完成后务必关闭客户端。
$ dart main.dart Status code: 200 Headers: {content-encoding: gzip, accept-ranges: bytes, ...} Body length: 1256
处理响应标头
本示例演示了访问和使用响应头。
import 'dart:io'; Future<void> main() async { var client = HttpClient(); try { var request = await client.getUrl(Uri.parse('https://example.com')); var response = await request.close(); print('Content-Type: ${response.headers.contentType}'); print('Content-Length: ${response.contentLength}'); print('Last-Modified: ${response.headers.value('last-modified')}'); response.headers.forEach((name, values) { print('$name: $values'); }); } finally { client.close(); } }
我们通过方便的属性访问常用头,并遍历所有头。头是大小写不敏感的,并且可能具有多个值。
$ dart main.dart Content-Type: text/html; charset=UTF-8 Content-Length: 648 Last-Modified: null content-encoding: [gzip] accept-ranges: [bytes] ...
将响应读取为 JSON
本示例展示了如何解析 API 的 JSON 响应。
import 'dart:io'; import 'dart:convert'; Future<void> main() async { var client = HttpClient(); try { var request = await client.getUrl( Uri.parse('https://jsonplaceholder.typicode.com/todos/1') ); var response = await request.close(); if (response.statusCode == 200) { var jsonString = await response.transform(utf8.decoder).join(); var json = jsonDecode(jsonString); print('Todo ID: ${json['id']}'); print('Title: ${json['title']}'); print('Completed: ${json['completed']}'); } else { print('Request failed with status: ${response.statusCode}'); } } finally { client.close(); } }
我们获取一个 JSON 资源,解码响应体,并访问解析后的数据。在 JSON 解析之前,将响应流转换为 UTF-8。
$ dart main.dart Todo ID: 1 Title: delectus aut autem Completed: false
处理大型响应
本示例演示了分块流式传输大型响应。
import 'dart:io'; import 'dart:convert'; Future<void> main() async { var client = HttpClient(); try { var request = await client.getUrl( Uri.parse('https://example.com/large-file') ); var response = await request.close(); var file = File('large_file.txt').openWrite(); var byteCount = 0; await response.listen((List<int> chunk) { byteCount += chunk.length; file.add(chunk); print('Received ${chunk.length} bytes (total: $byteCount)'); }).asFuture(); await file.close(); print('File saved with $byteCount bytes'); } finally { client.close(); } }
我们将大型响应直接流式传输到文件,而无需将其全部加载到内存中。listen() 方法处理从服务器到达的每个块。
$ dart main.dart Received 16384 bytes (total: 16384) Received 16384 bytes (total: 32768) ... File saved with 5242880 bytes
错误处理
本示例展示了 HTTP 请求的正确错误处理。
import 'dart:io'; import 'dart:convert'; Future<void> main() async { var client = HttpClient(); try { var request = await client.getUrl( Uri.parse('https://nonexistent.example.com') ); var response = await request.close(); var body = await response.transform(utf8.decoder).join(); print(body); } on SocketException catch (e) { print('Network error: $e'); } on HttpException catch (e) { print('HTTP error: $e'); } on FormatException catch (e) { print('Format error: $e'); } finally { client.close(); } }
我们处理 HTTP 请求期间可能发生的各种类型的异常。SocketException 涵盖网络问题,HttpException 涵盖 HTTP 错误。
$ dart main.dart Network error: SocketException: Failed host lookup: 'nonexistent.example.com'
最佳实践
- 务必关闭:完成时确保 HttpClient 已关闭
- 消耗响应:读取或取消所有响应流
- 使用转换:在需要时将字节流转换为文本
- 处理错误:适当地捕获特定异常
- 检查状态:在处理响应体之前验证 statusCode
来源
本教程涵盖了 Dart 的 HttpClientResponse 类,并提供了实际示例,展示了响应处理、流式传输、错误管理和最佳实践。
作者
列出 所有 Dart 教程。