Flutter集成1Fichier API上传卡滞:验证请求无法推进求助
Flutter 1Fichier上传验证请求卡住问题
程序执行到“发送验证请求...”步骤时卡住,无法继续推进。怀疑verifyUpload方法存在错误,或文件未实际上传成功(1Fichier平台无新增文件)。以下是完整代码:
主程序入口
import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:file_picker/file_picker.dart'; import 'package:path/path.dart'; // 用于获取文件名(basename) void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '1Fichier Uploader', theme: ThemeData(primarySwatch: Colors.blue), home: HomePage(), ); } }
上传工具类
class FichierUploader { Future<Map<String, String>?> getLinkAndId() async { debugPrint('调用getLink'); var uri = Uri.parse("https://api.1fichier.com/v1/upload/get_upload_server.cgi"); try { var response = await http.get( uri, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, ); if (response.statusCode == 200) { Map<String, dynamic> data = jsonDecode(response.body); if (data.containsKey('url') && data.containsKey('id')) { String url = data['url']; String id = data['id']; debugPrint('URL: $url'); debugPrint('ID: $id'); return {'url': url, 'id': id}; } else { debugPrint('JSON响应不完整 : ${response.body}'); } } else { debugPrint('错误: ${response.statusCode} - ${response.body}'); } } catch (e) { debugPrint('请求时出错: $e'); } return null; } Future<void> upload(File file) async { Map<String, String>? linkData = await getLinkAndId(); String apiKey = "EWAi0q8s8z2htQjJe90T7j=6OqBKncgo"; if (linkData != null) { String url = linkData['url']!; String id = linkData['id']!; debugPrint('🚀 开始上传,URL: $url ,ID: $id'); var uri = Uri.parse("https://$url/upload.cgi?id=$id"); debugPrint('🌍 上传URL: $uri'); try { http.MultipartRequest request = http.MultipartRequest('POST', uri); // 添加Authorization request.headers['Authorization'] = 'Bearer $apiKey'; // 添加文件,字段为"file[]"并指定文件名 if (file.existsSync()) { request.files.add( await http.MultipartFile.fromPath( 'file[]', file.path, filename: basename(file.path), ), ); } else { debugPrint('⚠️ 指定位置的文件不存在。'); return; } // 发送请求 var response = await request.send(); if (response.statusCode == 200) { debugPrint('✅ 上传成功(200) : 程序已正常完成。'); // 等待几秒让服务器处理上传 await Future.delayed(const Duration(seconds: 5)); await verifUpload(url, id); } else if (response.statusCode == 302) { // 处理重定向 String? redirectionUrl = response.headers['location']; if (redirectionUrl != null) { String fullRedirectionUrl = "https://$url$redirectionUrl"; debugPrint('🔄 重定向(302) : 点击链接查看报告 -> $fullRedirectionUrl'); await Future.delayed(const Duration(seconds: 5)); await verifUpload(url, id); } else { debugPrint('⚠️ 检测到重定向(302)但未提供URL。'); } } else if (response.statusCode == 500) { debugPrint('❌ 服务器内部错误(500) : 无法恢复的错误。'); } else { debugPrint('⚠️ 意外错误(${response.statusCode}) : ${await response.stream.bytesToString()}'); } } catch (e) { debugPrint('🛑 上传时出错 : $e'); } } else { debugPrint('❌ 无法获取上传信息。'); } } Future<void> verifUpload(String url, String id) async { debugPrint('🚀 开始验证,URL: $url ,ID: $id'); // 使用JSON=2用于调试 var uri = Uri.parse("https://$url/end.pl?xid=$id&JSON=2"); debugPrint('🌍 验证URL: $uri'); try { debugPrint('发送验证请求...'); // 超时时间增加到60秒 var response = await http.get(uri).timeout(const Duration(seconds: 60)); debugPrint('请求已发送。状态码: ${response.statusCode}'); debugPrint('响应内容: ${response.body}'); if (response.statusCode == 200) { debugPrint('✅ 验证成功,已收到JSON响应。'); Map<String, dynamic> jsonResponse = jsonDecode(response.body); if (jsonResponse.containsKey('links') && jsonResponse['links'].isNotEmpty) { var linkData = jsonResponse['links'][0]; String downloadLink = linkData['download']; String filename = linkData['filename']; String removeLink = linkData['remove']; String size = linkData['size']; debugPrint('🔗 下载链接: $downloadLink'); debugPrint('📄 文件名: $filename'); debugPrint('🗑 删除链接: $removeLink'); debugPrint('📦 文件大小: $size'); } else { debugPrint('⚠️ 响应JSON中未找到链接。'); } } else { debugPrint('⚠️ 意外响应(${response.statusCode}) : ${response.body}'); } } catch (e) { debugPrint('🛑 验证时出错 : $e'); } } }
主页Widget
class HomePage extends StatefulWidget { const HomePage({super.key}); @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { File? selectedFile; Future<void> selectFile() async { FilePickerResult? result = await FilePicker.platform.pickFiles(); if (result != null) { setState(() { selectedFile = File(result.files.single.path!); }); debugPrint('已选择文件: ${selectedFile!.path}'); } else { debugPrint('未选择任何文件。'); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('上传到1Fichier')), body: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ ElevatedButton( onPressed: selectFile, child: const Text('选择文件'), ), const SizedBox(height: 20), selectedFile == null ? const Text('未选择任何文件') : Text('已选择文件: ${selectedFile!.path}'), const SizedBox(height: 20), ElevatedButton( onPressed: selectedFile != null ? () => FichierUploader().upload(selectedFile!) : null, child: const Text('上传'), ), ], ), ), ); } }
问题排查与修复方案
1. 上传请求缺少必要参数
根据1Fichier API规范,上传请求除了Authorization和file[],还需携带id参数作为表单字段。修改upload方法,在添加文件后新增:
request.fields['id'] = id;
2. 验证请求参数错误
当前验证请求使用了错误的参数名xid,正确参数应为id。修改verifUpload方法中的URL:
var uri = Uri.parse("https://$url/end.pl?id=$id&JSON=2");
3. 优化上传后等待逻辑
无需固定等待5秒,可缩短等待时间至2秒,避免不必要的阻塞:
await Future.delayed(const Duration(seconds: 2));
4. 明确超时异常处理
为验证请求添加更清晰的超时提示,区分超时与其他异常:
try { var response = await http.get(uri).timeout( const Duration(seconds: 60), onTimeout: () { debugPrint('🛑 验证请求超时'); return http.Response('Timeout', 408); }, ); // 后续响应处理逻辑 } on TimeoutException catch (_) { debugPrint('🛑 验证请求超时'); } catch (e) { debugPrint('🛑 验证时出错 : $e'); }
5. 检查API密钥权限
确认你的API密钥拥有上传权限,可通过官方API文档的测试接口验证密钥有效性。
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

