Flutter 通过 rest api 端点上传文件
Flutter upload file through rest api endpoint
我有一个 flutter 应用程序,它通过 REST api 与服务器交互,它可以在其中获取和显示信息。它还可以向服务器发送文本信息。我想添加将 pdf 文件和图像发送到服务器的功能,但我不知道如何实现。这是选择文件的代码
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Another Attempt'),
centerTitle: true,
),
body: Container(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
MaterialButton(
onPressed: () async {
FilePickerResult result =
await FilePicker.platform.pickFiles(allowMultiple: true);
if (result != null) {
List<File> files =
result.paths.map((path) => File(path)).toList();
} else {
// User canceled the picker
}
},
child: Text('Upload multiple files'),
color: Colors.blueAccent,
),
SizedBox(height: 10.0),
MaterialButton(
onPressed: () async {
FilePickerResult result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}
},
child: Text('Upload single file'),
color: Colors.blueAccent,
),
SizedBox(height: 10.0),
MaterialButton(
onPressed: () {
_submitData();
},
child: Text('Upload single file'),
color: Colors.blueAccent,
),
],
),
),
);
}
void _submitData() async {
setState(() {});
var data = {
'image': file,
'pdf': files,
};
try {
var res = await Network().postData(data, '/convert-customer');
var body = json.decode(res.body);
if (res.statusCode == 200 || res.statusCode == 201) {
print(res.statusCode);
print(body);
} else {}
} on TimeoutException catch (_) {
print("Your connection has timedout");
_formKey.currentState.reset();
} on SocketException catch (_) {
print("You are not connected to internet");
_formKey.currentState.reset();
}
setState(() {
_isLoading = false;
});
}
这是向服务器发送数据的代码
final String _baseUrl = 'http://106.20.34.127/trial/api/v1';
var token;
_getToken() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
token = jsonDecode(localStorage.getString('token'))['token'];
}
postData(data, apiUrl) async {
try {
var _finalUrl = _baseUrl + apiUrl;
Uri fullUrl = Uri.parse(_finalUrl);
await _getToken();
print(fullUrl);
return await http.post(fullUrl,
body: jsonEncode(data), headers: _setHeaders());
} catch (e) {
print(e);
}
}
我该怎么做。
对文件使用 http.MultipartRequest 而不是 http.post。通常,POST 请求的正文由文本键值对组成。对于多部分 POST 请求,除了常规文本值之外,您还可以包含具有二进制内容(图像、各种文档等)的文件。
import 'package:http/http.dart' as http;
var req = http.MultipartRequest('POST', Uri.parse(url));
这个 req 对象有一个名为 fields 的成员 Map 用于文本值和一个 List 调用了 files,您可以向其中添加 MultipartFiles。
这整个事情中最重要的元素是 MultipartFile。它可以通过几种方式构建:
默认的MultipartFile(key, stream, length)构造函数,
如果您需要从字节流创建文件,则可以使用
我们知道长度。
MultipartFile.fromBytes(key, bytes)工厂方法,其中
附加从字节列表中获得的文件。
MultipartFile.fromString(key, string) 工厂方法,它附加一个包含传递给它的字符串的文本文件。
MultipartFile.fromPath(key, path) 工厂方法,附加在给定路径找到的文件。
示例:使用 MultipartFile.fromPath() 您可以编写如下函数
(String filename, String url) async {
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(
await http.MultipartFile.fromPath(
'pdf',
filename
)
);
var res = await request.send();
}
或者您可以简单地使用 pub.dev
上提供的这个 multipart_request 插件
我有一个 flutter 应用程序,它通过 REST api 与服务器交互,它可以在其中获取和显示信息。它还可以向服务器发送文本信息。我想添加将 pdf 文件和图像发送到服务器的功能,但我不知道如何实现。这是选择文件的代码
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Another Attempt'),
centerTitle: true,
),
body: Container(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
MaterialButton(
onPressed: () async {
FilePickerResult result =
await FilePicker.platform.pickFiles(allowMultiple: true);
if (result != null) {
List<File> files =
result.paths.map((path) => File(path)).toList();
} else {
// User canceled the picker
}
},
child: Text('Upload multiple files'),
color: Colors.blueAccent,
),
SizedBox(height: 10.0),
MaterialButton(
onPressed: () async {
FilePickerResult result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}
},
child: Text('Upload single file'),
color: Colors.blueAccent,
),
SizedBox(height: 10.0),
MaterialButton(
onPressed: () {
_submitData();
},
child: Text('Upload single file'),
color: Colors.blueAccent,
),
],
),
),
);
}
void _submitData() async {
setState(() {});
var data = {
'image': file,
'pdf': files,
};
try {
var res = await Network().postData(data, '/convert-customer');
var body = json.decode(res.body);
if (res.statusCode == 200 || res.statusCode == 201) {
print(res.statusCode);
print(body);
} else {}
} on TimeoutException catch (_) {
print("Your connection has timedout");
_formKey.currentState.reset();
} on SocketException catch (_) {
print("You are not connected to internet");
_formKey.currentState.reset();
}
setState(() {
_isLoading = false;
});
}
这是向服务器发送数据的代码
final String _baseUrl = 'http://106.20.34.127/trial/api/v1';
var token;
_getToken() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
token = jsonDecode(localStorage.getString('token'))['token'];
}
postData(data, apiUrl) async {
try {
var _finalUrl = _baseUrl + apiUrl;
Uri fullUrl = Uri.parse(_finalUrl);
await _getToken();
print(fullUrl);
return await http.post(fullUrl,
body: jsonEncode(data), headers: _setHeaders());
} catch (e) {
print(e);
}
}
我该怎么做。
对文件使用 http.MultipartRequest 而不是 http.post。通常,POST 请求的正文由文本键值对组成。对于多部分 POST 请求,除了常规文本值之外,您还可以包含具有二进制内容(图像、各种文档等)的文件。
import 'package:http/http.dart' as http;
var req = http.MultipartRequest('POST', Uri.parse(url));
这个 req 对象有一个名为 fields 的成员 Map 用于文本值和一个 List 调用了 files,您可以向其中添加 MultipartFiles。
这整个事情中最重要的元素是 MultipartFile。它可以通过几种方式构建:
默认的MultipartFile(key, stream, length)构造函数, 如果您需要从字节流创建文件,则可以使用 我们知道长度。
MultipartFile.fromBytes(key, bytes)工厂方法,其中 附加从字节列表中获得的文件。
MultipartFile.fromString(key, string) 工厂方法,它附加一个包含传递给它的字符串的文本文件。
MultipartFile.fromPath(key, path) 工厂方法,附加在给定路径找到的文件。
示例:使用 MultipartFile.fromPath() 您可以编写如下函数
(String filename, String url) async {
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(
await http.MultipartFile.fromPath(
'pdf',
filename
)
);
var res = await request.send();
}
或者您可以简单地使用 pub.dev
上提供的这个 multipart_request 插件