ZetCode

Dart ContentType

最后修改于 2025 年 4 月 4 日

Dart 中的 ContentType 类表示 HTTP 标头和内容协商中使用的 MIME 类型。它对于 Web 开发和数据交换至关重要。

ContentType 处理媒体类型、字符编码和参数。它是 Dart 的 dart:io 库(用于服务器端应用程序)和 dart:http 库(用于客户端)的一部分。

基本定义

ContentType 表示一个带有可选参数的 MIME 类型。它根据 RFC 2045 和 RFC 2616 解析和格式化 content-type 标头。

关键属性包括主类型、子类型、字符集和参数。该类提供了常见 MIME 类型的常量和解析实用程序。

创建 ContentType 对象

此示例演示了创建 ContentType 实例的不同方法。

main.dart
import 'dart:io';

void main() {
  // Using constructor
  var jsonType = ContentType('application', 'json');
  
  // Using parse
  var htmlType = ContentType.parse('text/html; charset=utf-8');
  
  // Using predefined constants
  var textPlain = ContentType.text;
  
  print('JSON: $jsonType');
  print('HTML: $htmlType');
  print('Text: $textPlain');
}

我们演示了三种创建方法:直接构造函数、从字符串解析以及使用预定义常量。每种方法都会生成一个有效的 ContentType 对象。

$ dart main.dart
JSON: application/json
HTML: text/html; charset=utf-8
Text: text/plain

处理参数

此示例演示了如何处理 MIME 类型参数,例如字符集。

main.dart
import 'dart:io';

void main() {
  var contentType = ContentType('text', 'html',
      parameters: {'charset': 'utf-8', 'version': '1.0'});
  
  print('Primary type: ${contentType.primaryType}');
  print('Subtype: ${contentType.subType}');
  print('Charset: ${contentType.charset}');
  print('Version: ${contentType.parameters['version']}');
  
  // Modify parameters
  contentType.charset = 'iso-8859-1';
  print('Modified: $contentType');
}

我们创建一个带有附加参数的 ContentType 并演示如何访问它们。字符集属性作为常见参数具有特殊处理。

$ dart main.dart
Primary type: text
Subtype: html
Charset: utf-8
Version: 1.0
Modified: text/html; charset=iso-8859-1; version=1.0

HTTP 标头解析

此示例演示了从 HTTP 请求解析 Content-Type 标头。

main.dart
import 'dart:io';

void main() {
  var headers = {
    'content-type': 'application/json; charset=utf-8',
    'accept': 'text/html, application/xhtml+xml'
  };
  
  // Parse request content type
  var contentType = ContentType.parse(headers['content-type']!);
  print('Content-Type: $contentType');
  
  // Parse accept header (multiple types)
  var acceptTypes = headers['accept']!
      .split(',')
      .map((s) => ContentType.parse(s.trim()))
      .toList();
  
  print('Accept types:');
  acceptTypes.forEach(print);
}

我们同时解析 Content-Type 和 Accept 标头。Accept 标头需要特殊处理,因为它可能包含带有质量因子的多个 MIME 类型。

$ dart main.dart
Content-Type: application/json; charset=utf-8
Accept types:
text/html
application/xhtml+xml

内容协商

此示例展示了使用 ContentType 进行基本内容协商。

main.dart
import 'dart:io';

void main() {
  var serverOffers = [
    ContentType('text', 'html'),
    ContentType('application', 'json'),
    ContentType('text', 'plain')
  ];
  
  var clientAccepts = [
    ContentType.parse('application/json;q=0.9'),
    ContentType.parse('text/*;q=0.8'),
    ContentType.parse('*/*;q=0.1')
  ];
  
  // Find best match
  var bestMatch = _negotiateContent(serverOffers, clientAccepts);
  print('Best match: $bestMatch');
}

ContentType? _negotiateContent(
    List<ContentType> offers, List<ContentType> accepts) {
  for (var accept in accepts) {
    for (var offer in offers) {
      if ((accept.primaryType == '*' || 
           accept.primaryType == offer.primaryType) &&
          (accept.subType == '*' || 
           accept.subType == offer.subType)) {
        return offer;
      }
    }
  }
  return null;
}

我们通过匹配客户端偏好与服务器提供的匹配来实现简单的内容协商。类型/子类型中支持通配符(*)。

$ dart main.dart
Best match: application/json

构建 HTTP 响应

此示例展示了如何在 HTTP 响应中设置 Content-Type 标头。

main.dart
import 'dart:io';

void main() async {
  var server = await HttpServer.bind('localhost', 8080);
  print('Server running on port 8080');
  
  await for (var request in server) {
    var response = request.response;
    
    // Set content type based on request
    if (request.uri.path.endsWith('.json')) {
      response.headers.contentType = ContentType.json;
    } else if (request.uri.path.endsWith('.html')) {
      response.headers.contentType = ContentType.html;
    } else {
      response.headers.contentType = ContentType.text;
    }
    
    response.write('Response with ${response.headers.contentType}');
    await response.close();
  }
}

我们创建一个简单的 HTTP 服务器,根据请求的资源扩展名设置 Content-Type。ContentType 类可确保正确的标头格式。

$ dart main.dart
Server running on port 8080

最佳实践

来源

Dart ContentType 文档

本教程介绍了 Dart 的 ContentType 类,并通过实际示例展示了创建、解析、内容协商和 HTTP 标头处理。

作者

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

列出 所有 Dart 教程