You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何获取含文件的MultipartRequest原始字符串?

解决方案

1. 问题根源

Multipart请求的请求体包含二进制文件内容,并非纯UTF-8编码文本,直接用utf.decode()转换必然触发FormatException。正确思路是直接用二进制数据参与签名计算,而非强行转成字符串。

2. 针对MultipartRequest的处理步骤

步骤1:构造请求并获取二进制请求体

import 'package:http/http.dart' as http;

// 构造Multipart请求
var request = http.MultipartRequest('POST', Uri.parse('你的API地址'));
// 添加文本字段
request.fields['username'] = 'test_user';
// 添加文件
request.files.add(await http.MultipartFile.fromPath('avatar', '/path/to/avatar.jpg'));

// 获取完整二进制请求体
List<int> requestBodyBytes = await request.finalize().toBytes();

步骤2:生成签名

按照API规范拼接负载前缀,再与请求体二进制合并后计算HMAC-SHA256:

import 'dart:convert';
import 'package:crypto/crypto.dart';

// 按规范提取各字段
String path = '/user/avatar'; // 主机/api之后的路径,不含查询参数
String verb = 'POST';
String token = 'Bearer xxxxxx';
String timestamp = DateTime.utc.now().toIso8601String(); // 确保是UTC+0的ISO8601格式

// 构造签名前缀字节
String prefixStr = 'path=$path&verb=$verb&token=$token&timestamp=$timestamp&body=';
List<int> prefixBytes = utf8.encode(prefixStr);

// 合并前缀与请求体二进制
List<int> signaturePayload = [...prefixBytes, ...requestBodyBytes];

// 计算HMAC-SHA256并base64编码
String secretKey = '你的密钥';
Hmac hmac = Hmac(sha256, utf8.encode(secretKey));
Digest digest = hmac.convert(signaturePayload);
String signature = base64.encode(digest.bytes);

3. 针对Dio FormData的处理步骤

步骤1:构造FormData并获取二进制请求体

import 'package:dio/dio.dart';

// 构造FormData
var formData = FormData.fromMap({
  'username': 'test_user',
  'avatar': await MultipartFile.fromFile('/path/to/avatar.jpg'),
});

// 获取二进制请求体
List<int> requestBodyBytes = await formData.finalize();

步骤2:生成签名

和MultipartRequest的签名生成逻辑完全一致,用前缀字节拼接请求体二进制后计算签名即可。

4. 特殊情况确认

如果上述方法不符合API要求,需确认:

  • API是否仅要求签名包含文本字段,而非整个Multipart请求体?若是,单独提取文本字段拼接成指定格式字符串即可。
  • API是否要求对Multipart请求体先做base64编码,再加入签名负载?若是,先将请求体二进制转base64字符串,再拼接到前缀中。

内容的提问来源于stack exchange,提问作者Dias Utsman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 15:02:06