Flutter中如何展示带Token的API请求返回的PDF文件?
Flutter加载带Token鉴权的PDF解决方案
问题根因
你现有代码的核心错误点如下:
- 请求头
Accept配置为application/json,告知服务端你期望返回JSON格式,但接口实际返回PDF二进制流,会导致服务端返回格式错误或406状态码 - 没有对接口响应做状态校验,可能拿到的是错误响应的字节流,而非合法PDF内容
- GET请求不需要配置
Content-type请求头,该头是用于声明请求体的格式,GET请求无请求体
依赖配置
先确认pubspec.yaml已引入所需依赖:
dependencies: http: ^1.1.0 path_provider: ^2.1.0 flutter_pdfview: ^1.3.2
修正后代码实现
1. PDF请求与临时文件生成逻辑
import 'dart:io'; import 'package:http/http.dart' as http; import 'package:path_provider/path_provider.dart'; File? localPdfFile; Future<void> loadCertificatePdf(String apiUrl) async { final Map<String, String> headers = { 'Accept': 'application/pdf', 'Authorization': 'Bearer $userToken' }; try { final response = await http.get(Uri.parse(apiUrl), headers: headers); // 校验请求是否成功 if (response.statusCode != 200) { throw Exception('PDF获取失败,状态码:${response.statusCode}'); } // 写入临时文件 final tempDir = await getTemporaryDirectory(); final pdfFile = File('${tempDir.path}/user_certificate.pdf'); await pdfFile.writeAsBytes(response.bodyBytes, flush: true); setState(() { localPdfFile = pdfFile; }); } catch (err) { // 可自行添加错误提示逻辑 print('PDF加载失败:$err'); } }
2. 页面渲染PDF逻辑
import 'package:flutter_pdfview/flutter_pdfview.dart'; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('课程证书')), body: localPdfFile == null ? const Center(child: CircularProgressIndicator()) : PDFView( filePath: localPdfFile!.path, onError: (error) => print('PDF渲染错误:$error'), onPageError: (page, error) => print('第$page页加载失败:$error'), ), ); }
兼容适配
- 安卓端:在
android/app/src/main/AndroidManifest.xml的<application>标签添加属性android:requestLegacyExternalStorage="true",适配安卓10以上的存储权限 - iOS端:如果接口为HTTP协议,需要在
ios/Runner/Info.plist中添加NSAppTransportSecurity的HTTP白名单配置 - 如果PDF打开为空,可打印
response.bodyBytes.length和响应头的Content-Length对比,排查是否存在字节截断问题
内容的提问来源于stack exchange,提问作者Max33
相关产品推荐
相关产品推荐

