ZetCode

Dart HttpResponse

最后修改于 2025 年 4 月 4 日

Dart 中的 HttpResponse 类提供了在服务器应用程序中处理 HTTP 响应的功能。它是服务器端 Dart 编程的 dart:io 库的一部分。

HttpResponse 允许设置状态码、标头和写入响应正文。它通常与 HttpServer 一起用于创建 Web 服务器和 HTTP 服务。

基本定义

HttpResponse 表示可以发送回客户端的 HTTP 响应。它提供了控制响应状态、标头和正文的方法。

主要功能包括状态码管理、标头操作以及多种写入响应数据的方式。它与 HttpRequest 对象结合使用。

基本 HTTP 服务器响应

本示例展示了一个返回文本响应的简单 HTTP 服务器。

main.dart
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  print('Server running on ${server.address}:${server.port}');

  await for (HttpRequest request in server) {
    request.response
      ..statusCode = HttpStatus.ok
      ..write('Hello, World!')
      ..close();
  }
}

我们创建一个监听 8080 端口的 HTTP 服务器。对于每个请求,我们将状态码设置为 200 (OK),写入响应,然后关闭连接。

$ dart main.dart
Server running on InternetAddress('127.0.0.1', IPv4):8080

设置响应标头

本示例演示了如何设置各种 HTTP 响应标头。

main.dart
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  
  await for (HttpRequest request in server) {
    request.response
      ..headers.contentType = ContentType.html
      ..headers.set('X-Custom-Header', 'DartServer')
      ..headers.date = DateTime.now()
      ..write('''
        <html>
          <body>
            <h1>Hello from Dart!</h1>
          </body>
        </html>
      ''')
      ..close();
  }
}

我们设置内容类型为 HTML,添加一个自定义标头,并设置响应日期。headers 属性提供了对响应所有 HTTP 标头的访问。

$ dart main.dart

提供 JSON 数据

本示例展示了如何从 HTTP 服务器返回 JSON 数据。

main.dart
import 'dart:io';
import 'dart:convert';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  
  await for (HttpRequest request in server) {
    final data = {
      'message': 'Hello from Dart',
      'timestamp': DateTime.now().toIso8601String(),
      'status': 'success'
    };
    
    request.response
      ..statusCode = HttpStatus.ok
      ..headers.contentType = ContentType.json
      ..write(jsonEncode(data))
      ..close();
  }
}

我们用数据创建一个 Dart Map,将内容类型设置为 JSON,然后将数据编码为 JSON 格式,再写入响应。

$ dart main.dart

处理不同的状态码

本示例演示了如何在响应中使用不同的 HTTP 状态码。

main.dart
import 'dart:io';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  
  await for (HttpRequest request in server) {
    try {
      if (request.uri.path == '/secret') {
        request.response
          ..statusCode = HttpStatus.forbidden
          ..write('Access denied')
          ..close();
      } else if (request.uri.path == '/notfound') {
        request.response
          ..statusCode = HttpStatus.notFound
          ..write('Page not found')
          ..close();
      } else {
        request.response
          ..statusCode = HttpStatus.ok
          ..write('Welcome!')
          ..close();
      }
    } catch (e) {
      request.response
        ..statusCode = HttpStatus.internalServerError
        ..write('Server error: $e')
        ..close();
    }
  }
}

我们检查请求路径并相应地返回不同的状态码。这展示了如何在 Web 服务器应用程序中处理各种场景。

$ dart main.dart

流式传输大型响应

本示例演示了如何高效地流式传输大型响应。

main.dart
import 'dart:io';
import 'dart:async';

Future<void> main() async {
  final server = await HttpServer.bind('localhost', 8080);
  
  await for (HttpRequest request in server) {
    if (request.uri.path == '/stream') {
      final response = request.response;
      response.headers.contentType = ContentType.text;
      
      final timer = Timer.periodic(Duration(seconds: 1), (timer) {
        response.write('Data chunk at ${DateTime.now()}\n');
        if (timer.tick >= 5) {
          timer.cancel();
          response.close();
        }
      });
    } else {
      request.response
        ..write('Send request to /stream for streaming data')
        ..close();
    }
  }
}

我们创建一个流式响应,在 5 秒内每秒发送数据块。这对于大型响应或实时数据非常有用,而无需一次将所有数据加载到内存中。

$ dart main.dart

最佳实践

来源

Dart HttpResponse 文档

本教程介绍了 Dart 的 HttpResponse 类,并通过实际示例展示了基本用法、标头管理、状态码和流式响应。

作者

我叫 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年起撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 Dart 教程