ZetCode

Dart RedirectInfo

最后修改于 2025 年 4 月 4 日

Dart 中的 RedirectInfo 类提供了有关网络请求期间发生的 HTTP 重定向的信息。它是 Dart 的 dart:io 库的一部分,用于服务器端和命令行应用程序。

RedirectInfo 包含有关重定向响应的详细信息,包括状态码、位置和方法。它有助于跟踪和分析 HTTP 通信中的重定向链。

基本定义

RedirectInfo 是一个表示单个 HTTP 重定向的不可变类。它通常从 HttpClientResponse 的 redirects 属性中获取。

关键属性包括 statusCode、method 和 location。这些有助于理解和处理 HTTP 客户端和服务器中的重定向。

RedirectInfo 基本用法

此示例展示了如何从 HTTP 客户端响应中访问 RedirectInfo。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  
  try {
    var request = await client.getUrl(Uri.parse('http://example.org'));
    var response = await request.close();
    
    if (response.redirects.isNotEmpty) {
      var redirect = response.redirects.first;
      print('Redirected to: ${redirect.location}');
      print('Status code: ${redirect.statusCode}');
      print('Method: ${redirect.method}');
    }
  } finally {
    client.close();
  }
}

我们创建一个 HTTP 客户端并检查响应中的重定向。如果发生任何重定向,将打印第一个重定向的详细信息。

$ dart main.dart
Redirected to: https://example.org/
Status code: 301
Method: GET

分析重定向链

此示例演示了检查完整的重定向链。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  
  try {
    var request = await client.getUrl(Uri.parse('http://google.com'));
    var response = await request.close();
    
    print('Final URL: ${response.redirects.last.location}');
    print('Redirect chain length: ${response.redirects.length}');
    
    for (var redirect in response.redirects) {
      print('${redirect.statusCode} ${redirect.method} -> ${redirect.location}');
    }
  } finally {
    client.close();
  }
}

我们打印链中的每个重定向及其状态码和方法。这有助于理解复杂的重定向序列。

$ dart main.dart
Final URL: https://www.google.com/
Redirect chain length: 2
301 GET -> https://google.com/
301 GET -> https://www.google.com/

手动跟踪重定向

此示例展示了使用 RedirectInfo 手动跟踪重定向。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  var url = Uri.parse('http://example.org');
  var maxRedirects = 5;
  var currentRedirect = 0;
  
  try {
    while (currentRedirect < maxRedirects) {
      var request = await client.getUrl(url);
      var response = await request.close();
      
      if (response.redirects.isEmpty) {
        print('Final destination: $url');
        break;
      }
      
      var redirect = response.redirects.first;
      print('Redirect $currentRedirect: ${redirect.location}');
      url = Uri.parse(redirect.location.toString());
      currentRedirect++;
    }
  } finally {
    client.close();
  }
}

我们将重定向手动跟踪到一个最大限制。这演示了如何在需要时实现自定义重定向逻辑。

$ dart main.dart
Redirect 0: https://example.org/
Final destination: https://example.org/

处理不同的重定向类型

此示例展示了如何处理各种重定向状态码。

main.dart
import 'dart:io';

void main() async {
  var client = HttpClient();
  
  try {
    var request = await client.getUrl(Uri.parse('http://test.com/temporary'));
    var response = await request.close();
    
    if (response.redirects.isNotEmpty) {
      var redirect = response.redirects.first;
      
      switch (redirect.statusCode) {
        case HttpStatus.movedPermanently:
          print('Permanent redirect to ${redirect.location}');
          break;
        case HttpStatus.found:
          print('Temporary redirect to ${redirect.location}');
          break;
        case HttpStatus.seeOther:
          print('See other (change method to GET) to ${redirect.location}');
          break;
        default:
          print('Unknown redirect type: ${redirect.statusCode}');
      }
    }
  } finally {
    client.close();
  }
}

我们检查状态码以确定重定向类型。不同的 HTTP 状态码表示不同的重定向语义。

$ dart main.dart
Temporary redirect to http://test.com/new-location

创建自定义重定向策略

此示例演示了实现自定义重定向策略。

main.dart
import 'dart:io';

class SecureRedirectPolicy {
  bool allowRedirect(RedirectInfo redirect) {
    if (redirect.location.scheme != 'https') {
      print('Blocking insecure redirect to ${redirect.location}');
      return false;
    }
    return true;
  }
}

void main() async {
  var client = HttpClient();
  var policy = SecureRedirectPolicy();
  
  try {
    client.maxRedirects = 10;
    client.autoUncompress = false;
    
    var request = await client.getUrl(Uri.parse('http://bank.com/login'));
    var response = await request.close();
    
    for (var redirect in response.redirects) {
      if (!policy.allowRedirect(redirect)) {
        print('Aborting due to redirect policy violation');
        return;
      }
    }
    
    print('Successfully followed redirects to secure destination');
  } finally {
    client.close();
  }
}

我们实现了一个安全策略,该策略会阻止重定向到非 HTTPS URL。这展示了如何使用 RedirectInfo 进行安全验证。

$ dart main.dart
Blocking insecure redirect to http://bank.com/login
Aborting due to redirect policy violation

最佳实践

来源

Dart RedirectInfo 文档

本教程通过实际示例介绍了 Dart 的 RedirectInfo 类,展示了重定向处理、链分析和自定义安全策略。

作者

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

列出 所有 Dart 教程