Flutter中如何通过带请求头的POST请求下载用户专属PDF文件?
Flutter 带请求头POST请求下载用户专属PDF
核心思路
每个用户的专属PDF可通过两种方式实现:
- 后端根据请求中携带的用户身份标识(如
user_id、token)返回对应文件,请求URL统一但参数/请求头不同 - 后端为每个用户生成唯一的下载URL,前端根据用户ID拼接专属链接
无论哪种方式,核心都是用支持自定义请求头的HTTP库发起POST请求,获取文件流后保存到本地设备。
依赖准备
推荐使用dio处理HTTP请求(支持请求头配置、流式下载),搭配path_provider获取本地存储路径。在pubspec.yaml中添加:
dependencies: dio: ^5.4.0 path_provider: ^2.1.2
完整实现代码
1. 初始化Dio实例(配置全局请求头)
import 'dart:io'; import 'package:dio/dio.dart'; import 'package:path_provider/path_provider.dart'; // 初始化Dio,可提前配置通用请求头 final dio = Dio(BaseOptions( baseUrl: "https://your-backend-domain.com/", // 替换为你的后端域名 headers: { "Content-Type": "application/json", // 可添加固定请求头,如公共token }, ));
2. 生成用户专属请求参数/链接
// 示例:根据用户ID生成专属请求参数(或拼接专属URL) Map<String, dynamic> getUserRequestParams(String userId) { return { "user_id": userId, // 其他后端要求的参数,如签名等 }; } // 如果是专属URL的场景: String getUserDownloadUrl(String userId) { return "https://your-backend-domain.com/download/pdf?user_id=$userId"; }
3. 发起POST请求并下载PDF
Future<void> downloadUserPdf(String userId) async { try { // 1. 准备请求配置:添加用户专属请求头/参数 final options = Options( responseType: ResponseType.bytes, // 以字节流接收响应 headers: { "Authorization": "Bearer ${getUserToken()}", // 替换为用户的token "User-ID": userId, // 后端识别用户的标识 }, ); // 2. 发起POST请求 final response = await dio.post( "/api/download-pdf", // 替换为你的后端下载接口 data: getUserRequestParams(userId), // 携带用户参数 options: options, ); // 3. 获取本地存储路径 final directory = await getApplicationDocumentsDirectory(); final savePath = "${directory.path}/user_${userId}_document.pdf"; // 4. 将字节流写入文件 final file = File(savePath); await file.writeAsBytes(response.data); print("PDF已保存到:$savePath"); // 可添加打开文件的逻辑,如使用open_file包 } catch (e) { print("下载失败:${e.toString()}"); // 处理错误,如提示用户重试 } } // 示例:获取用户token的方法(根据你的登录逻辑实现) String getUserToken() { return "your_user_token_here"; }
关键注意事项
- 请求头验证:确保请求头包含后端要求的所有身份信息(如token、user_id),否则后端无法返回正确的用户专属PDF
- 权限配置:
- Android:在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />(针对旧版本系统) - iOS:在
Info.plist中添加NSDocumentsFolderUsageDescription说明文件存储用途
- Android:在
- 进度监听:如果需要显示下载进度,可在
dio.post中添加onReceiveProgress回调:onReceiveProgress: (count, total) { final progress = (count / total * 100).toStringAsFixed(0); print("下载进度:$progress%"); }, - 错误处理:捕获网络异常、文件写入异常等,给用户友好提示
内容的提问来源于stack exchange,提问作者Bill Tertis
相关产品推荐
相关产品推荐

