我已经为 Android 和 Web 创建了一个 Flutter 应用程序。在 Flutter Web 中,我尝试将图像上传到服务器,就像在 Firebase 中一样。但不知何故它不起作用。我已经看到了此任务的一些解决方案。但我想知道我的代码到底有什么问题。
final url = Uri.parse('$apiHeader/poststore');
String token = await getUserToken();
Map<String, String> headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token'
};
var request = http.MultipartRequest("POST", url);
request.headers.addAll(headers);
request.fields['category_id'] = model.categoryId;
request.fields['title'] = model.title;
//I want to know about this section of the code, how can i make it work
if (kIsWeb) {
final fileBytes =
await model.image.readAsBytes(); // convert into bytes
var multipartFile = http.MultipartFile.fromBytes(
'fileName[]', fileBytes); // add bytes to multipart
request.files.add(multipartFile);
} else {
var multipartFile = await http.MultipartFile.fromPath(
'fileName[]', model.image.path);
request.files.add(multipartFile);
}
var response = await request.send();
您的代码似乎非常适合将文件上传到 flutter web 中的 Firebase Storage。但它永远无法与 API 一起使用。 您只需更改文件选择方法即可。而不是
image_picker
或 file_picker
。您可以使用 universal_html
包,也可以简单地导入 html.dart
SDK 附带的 flutter
文件。
首先导入包
import 'package:universal_html/html.dart' as html;
现在使用此方法在网络中选择文件
Future<Either<String, html.File>> pickWebFile() async {
final Completer<Either<String, html.File>> completer = Completer();
html.FileUploadInputElement uploadInput = html.FileUploadInputElement();
uploadInput.accept = '.xlsx, .pdf'; // specify file extensions you want to pick
uploadInput.multiple = false;
uploadInput.click();
uploadInput.onChange.listen((e) {
final files = uploadInput.files;
if (files != null && files.isNotEmpty) {
final file = files.first;
completer.complete(Right(file));
} else {
completer.complete(const Left('No file selected'));
}
});
uploadInput.onError.listen((e) {
completer.complete(const Left('Error selecting file'));
});
return completer.future;
}
选择文件后,请调用此方法以使用 API 调用上传文件
Future<Either<String, String>> uploadFileToServer(html.File file) async {
final Completer<Either<String, String>> completer = Completer();
try {
User? user = FirebaseAuth.instance.currentUser;
if (user == null) {
return const Left('User is not logged in');
}
String? token = await user.getIdToken(true);
Uri url = Uri.parse(ApiEndpoints.uploadDoc);
final reader = html.FileReader();
reader.readAsArrayBuffer(file);
reader.onLoadEnd.listen((event) async {
try {
final fileBytes = reader.result as Uint8List;
var request = http.MultipartRequest('POST', url)
..headers['Authorization'] = 'Bearer $token'
..headers['Content-Type'] = 'multipart/form-data'
..files.add(http.MultipartFile.fromBytes('file', fileBytes, filename: file.name));
var response = await request.send();
var responseBody = await http.Response.fromStream(response);
if (response.statusCode == 200) {
debugPrint('File uploaded successfully: ${responseBody.body}');
completer.complete(const Right('File Uploaded Successfully!'));
} else {
debugPrint('Failed to upload file: ${response.statusCode}');
debugPrint('Response: ${responseBody.body}');
completer.complete(Left('Error: ${responseBody.body}'));
}
} catch (e) {
debugPrint('Error uploading file: $e');
completer.complete(Left('Error Uploading File: $e'));
}
});
reader.onError.listen((event) {
debugPrint('Error reading file: ${event.toString()}');
completer.complete(Left('Error: ${event.toString()}'));
});
} catch (e) {
debugPrint('Error uploading file: $e');
completer.complete(Left('Error Uploading File: $e'));
}
return completer.future;
}
请注意,您需要导入这些包才能使用此代码:
import 'dart:convert';
import 'package:dartz/dartz.dart';
import 'dart:io' as io;
import 'package:path/path.dart' as path;
import 'package:intl/intl.dart';
import 'package:http/http.dart' as http;
import 'package:universal_html/html.dart' as html;