Dart HttpOverrides
最后修改于 2025 年 4 月 4 日
Dart 中的 HttpOverrides 类允许自定义通过 dart:io HttpClient 发起的 HTTP 请求。它对于测试、模拟和修改 HTTP 行为非常有用。
HttpOverrides 提供了用于拦截和全局修改 HTTP 请求的钩子。这包括证书验证、代理配置和请求头。
基本定义
HttpOverrides 是 Dart dart:io 库中的一个抽象类。它作为 HTTP 请求自定义的全局钩子点。
关键方法包括用于客户端创建的 createHttpClient 和用于代理配置的 findProxy。这些方法可以被重写。
基本 HttpOverrides 用法
此示例展示了如何为所有 HTTP 请求设置基本的 HttpOverrides。
import 'dart:io';
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..userAgent = 'MyCustomAgent/1.0';
}
}
void main() async {
HttpOverrides.global = MyHttpOverrides();
final client = HttpClient();
final request = await client.getUrl(Uri.parse('https://example.com'));
final response = await request.close();
print('Request completed with status: ${response.statusCode}');
client.close();
}
我们创建了一个自定义的 HttpOverrides 类,为所有请求设置用户代理。全局实例在发起任何 HTTP 请求之前设置。
$ dart main.dart Request completed with status: 200
自定义证书验证
此示例演示了重写用于测试的证书验证。
import 'dart:io';
class TrustAllHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
void main() async {
HttpOverrides.global = TrustAllHttpOverrides();
try {
final client = HttpClient();
final request = await client.getUrl(
Uri.parse('https://self-signed.badssl.com/'));
final response = await request.close();
print('Successfully connected to self-signed cert site');
client.close();
} catch (e) {
print('Error: $e');
}
}
我们通过在回调中始终返回 true 来绕过证书验证。这对于测试很有用,但绝不应在生产代码中使用。
$ dart main.dart Successfully connected to self-signed cert site
代理配置
此示例展示了如何为所有 HTTP 请求配置代理。
import 'dart:io';
class ProxyHttpOverrides extends HttpOverrides {
@override
String findProxyFromEnvironment(Uri url, Map<String, String>? environment) {
return 'PROXY myproxy.example.com:8080';
}
}
void main() async {
HttpOverrides.global = ProxyHttpOverrides();
final client = HttpClient();
final request = await client.getUrl(Uri.parse('https://example.com'));
final response = await request.close();
print('Request completed via proxy');
client.close();
}
我们重写了代理配置,将所有请求通过指定的代理服务器路由。findProxyFromEnvironment 方法返回代理字符串。
$ dart main.dart Request completed via proxy
请求头修改
此示例演示了为所有请求添加自定义请求头。
import 'dart:io';
class CustomHeadersHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..addCredentials = _addCredentials
..addRequestHeaders = _addHeaders;
}
void _addCredentials(Uri url, String scheme, String realm) {
// Credential logic here
}
void _addHeaders(Uri url, HttpClientRequest request) {
request.headers.add('X-Custom-Header', 'MyValue');
request.headers.add('Authorization', 'Bearer mytoken');
}
}
void main() async {
HttpOverrides.global = CustomHeadersHttpOverrides();
final client = HttpClient();
final request = await client.getUrl(Uri.parse('https://example.com'));
final response = await request.close();
print('Request with custom headers completed');
client.close();
}
我们为每个传出请求添加了静态和动态请求头。addRequestHeaders 回调在每个请求发送之前被调用。
$ dart main.dart Request with custom headers completed
模拟 HTTP 响应
此示例展示了如何为测试目的模拟 HTTP 响应。
import 'dart:io';
import 'dart:convert';
class MockHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return _MockHttpClient();
}
}
class _MockHttpClient implements HttpClient {
@override
Future<HttpClientRequest> getUrl(Uri url) async {
return _MockHttpClientRequest();
}
// Other required overrides omitted for brevity
}
class _MockHttpClientRequest implements HttpClientRequest {
@override
Future<HttpClientResponse> close() async {
return _MockHttpClientResponse();
}
// Other required overrides omitted for brevity
}
class _MockHttpClientResponse implements HttpClientResponse {
@override
int get statusCode => 200;
@override
Stream<Uint8List> get body =>
Stream.value(utf8.encode('{"message": "Mock response"}'));
// Other required overrides omitted for brevity
}
void main() async {
HttpOverrides.global = MockHttpOverrides();
final client = HttpClient();
final request = await client.getUrl(Uri.parse('https://example.com'));
final response = await request.close();
final data = await response.transform(utf8.decoder).join();
print('Mock response: $data');
client.close();
}
我们实现了一个完整的模拟 HTTP 客户端,该客户端返回预定义的响应。这对于在不进行实际网络请求的情况下进行测试很有用。
$ dart main.dart
Mock response: {"message": "Mock response"}
最佳实践
- 仅用于测试: 仅在测试环境中使用证书绕过
- 性能: 保持 overrides 轻量级以避免减慢速度
- 安全:切勿在生产代码中硬编码凭据
- 清理:完成后重置 HttpOverrides.global
来源
本教程介绍了 Dart 的 HttpOverrides 类,并通过实际示例展示了请求自定义、代理设置和测试技术。
作者
列出 所有 Dart 教程。