我想上传图片,我正在使用 http.Client() 来发出请求,
static uploadImage(String id, File file) {
var httpClient = createHttpClient();
Map<String, String> headers = new Map<String, String>();
headers.putIfAbsent("Authorization", () => "---");
headers.putIfAbsent("Content-Type", () => "application/json");
var body=new List();
body.add(id.)
httpClient.post(URL_UPLOADIMAGE,headers: headers,body: ,encoding: )
}
请求的正文和编码部分应该是什么?
使用 MultipartRequest 类
Upload(File imageFile) async {
var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
var length = await imageFile.length();
var uri = Uri.parse(uploadURL);
var request = new http.MultipartRequest("POST", uri);
var multipartFile = new http.MultipartFile('file', stream, length,
filename: basename(imageFile.path));
//contentType: new MediaType('image', 'png'));
request.files.add(multipartFile);
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
名称空间:
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
最简单的方法是使用http库,
import 'dart:io';
import 'package:http/http.dart' as http;
_asyncFileUpload(String text, File file) async{
//create multipart request for POST or PATCH method
var request = http.MultipartRequest("POST", Uri.parse("<url>"));
//add text fields
request.fields["text_field"] = text;
//create multipart using filepath, string or bytes
var pic = await http.MultipartFile.fromPath("file_field", file.path);
//add multipart to request
request.files.add(pic);
var response = await request.send();
//Get the response from the server
var responseData = await response.stream.toBytes();
var responseString = String.fromCharCodes(responseData);
print(responseString);
}
用
submitForm()
方法检查身体。
File _image;
Future cameraImage() async {
var image = await ImagePicker.pickImage(
source: ImageSource.camera,
maxHeight: 240.0,
maxWidth: 240.0,
);
setState(() {
_image = image;
});
}
submitForm() async {
final response = await http.post(
uri,
headers: {
AuthUtils.AUTH_HEADER: _authToken
},
body: {
'user_id': userId
'photo': _image != null ? 'data:image/png;base64,' +
base64Encode(_image.readAsBytesSync()) : '',
},
);
final responseJson = json.decode(response.body);
print(responseJson);
}
我已经尝试了以上所有方法,但没有一个可以让我将文件上传到服务器。
经过深入搜索,我得到了一个和Dio一样的插件。
以下代码将文件上传到服务器。
uploadFileFromDio(UserProfile userProfile, File photoFile) async {
var dio = new Dio();
dio.options.baseUrl = url;
dio.options.connectTimeout = 5000; //5s
dio.options.receiveTimeout = 5000;
dio.options.headers = <Header Json>;
FormData formData = new FormData();
formData.add("user_id", userProfile.userId);
formData.add("name", userProfile.name);
formData.add("email", userProfile.email);
if (photoFile != null &&
photoFile.path != null &&
photoFile.path.isNotEmpty) {
// Create a FormData
String fileName = basename(photoFile.path);
print("File Name : $fileName");
print("File Size : ${photoFile.lengthSync()}");
formData.add("user_picture", new UploadFileInfo(photoFile, fileName));
}
var response = await dio.post("user/manage_profile",
data: formData,
options: Options(
method: 'POST',
responseType: ResponseType.PLAIN // or ResponseType.JSON
));
print("Response status: ${response.statusCode}");
print("Response data: ${response.data}");
}
我找到了一个不使用任何外部插件的工作示例,这个 只用
import 'package:http/http.dart' as http;
代码
var stream =
new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
// get file length
var length = await imageFile.length(); //imageFile is your image file
Map<String, String> headers = {
"Accept": "application/json",
"Authorization": "Bearer " + token
}; // ignore this headers if there is no authentication
// string to uri
var uri = Uri.parse(Constants.BASE_URL + "api endpoint here");
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// multipart that takes file
var multipartFileSign = new http.MultipartFile('profile_pic', stream, length,
filename: basename(imageFile.path));
// add file to multipart
request.files.add(multipartFileSign);
//add headers
request.headers.addAll(headers);
//adding params
request.fields['loginId'] = '12';
request.fields['firstName'] = 'abc';
// request.fields['lastName'] = 'efg';
// send
var response = await request.send();
print(response.statusCode);
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
请尝试以下解决方案
Future<String> uploadImageHTTP(file, url) async {
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(await http.MultipartFile.fromPath('picture', file.path));
var res = await request.send();
return res.reasonPhrase;
}
考虑使用 Flutter 的 Firebase Storage 插件——它具有可用于在移动连接上上传大型图像文件的功能。
我写了这个插件,欢迎贡献和反馈!
首先从图库或相机中选择您的图像
File _image;
Future _getImage() async {
var image = await ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
_image = image;
});
}
现在在按钮单击时或在 _getImage() 函数内调用以下函数。通过该文件,我上传了其他字段,您也可以在 saveInAttendance() 中看到
不要忘记导入包:
import 'package:dio/dio.dart';
import 'package:path/path.dart';
Future saveInAttendance( BuildContext context,String entryType,String mode) async {
Dio dio = new Dio();
FormData formData = new FormData(); // just like JS
formData.add("inimageFile", new UploadFileInfo(_image, basename(_image.path)));
formData.add("compID",2);
formData.add("company_id",2);
formData.add("EntryType", entryType);
formData.add("emp_code", 5);
formData.add("Mode",mode);
formData.add("location",""+_startLocation.latitude.toString()+"-"+_startLocation.longitude.toString());
dio.post(url_save_attendance, data: formData, options: Options(
method: 'POST',
responseType: ResponseType.json // or ResponseType.JSON
))
.then((r) {
setState(() {
var data = json.decode(r.toString());
if(data["apiMessage"].contains('Saved')){
warningAlert("Attendance Saved", "Your attendance saved Successfully",context);
}
});
}).catchError(print);
}
欲了解更多信息,您可以访问这里
从请求中获取正文而不是
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
我用:
String body=await response.stream.bytesToString()
我的工作代码如下,基于 @TejaDroid 的示例, 它通过 AWS Gateway API 上传一张图像,并使用后面的 lambda 函数将图像存储到 S3 中。
uploadImageWithhttp(File imageFile, int serialno) async {
var postBody= {
'username': '[email protected]',
"productid": "1000123", //TODO
"imageno": serialno.toString(),
'image': imageFile != null ? base64Encode(imageFile.readAsBytesSync()) : '',
};
final response = await http.post(
constAWSAPIGateway_UploadImage[CONST_API_STAGE],
headers: {
//AuthUtils.AUTH_HEADER: _authToken
'Content-Type' : 'application/json',
},
body: json.encode(postBody),
);
final responseJson = json.decode(response.body);
print(responseJson);
}
updateProfile() async {
try {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
var dio = new Dio();
var formData = FormData.fromMap({
'name': name,
'con_person_name': concernedPersonName,
'email': email,
'phone': phoneNumber,
'password': password,
'token': token,
'user_type': '3',
'license_no': licenceNumber,
'gstno': gstNumber,
'address': address,
'hospital_id': '102'
'image': await MultipartFile.fromFile(_image?.path,
filename: _image.path.split('/').last ?? 'image.jpeg'),
});
var response = await dio.post('$SERVER_ADDRESS/api/doctorregister',
data: formData);
print(response.statusCode);
print(response.data);
}
} catch (error) {
print(error.toString());
}
}
我找到了一种简单的方法来在 flutter 中上传图像,然后甚至在服务器上接收它。
颤动:
MaterialButton(
color: Colors.blue,
child: Text(
"Pick Image from Camera",
style: TextStyle(
color: Colors.white70, fontWeight: FontWeight.bold),
),
onPressed: () async {
final XFile? photo =
await _picker.pickImage(source: ImageSource.camera);
print(photo!.path);
await uploadImage(photo.path);
},
),
“上传图片”功能:
uploadImage(String filepath) async {
var url = 'http://192.168.75.57:4000/upload';
var request = http.MultipartRequest('POST', Uri.parse(url));
request.files.add(await http.MultipartFile.fromPath("img", filepath));
request.fields['_id'] = "abcdef";
request.headers.addAll({
"Content-type": "multipart/form-data",
});
var response = request.send();
return response;
}
在服务器端:(Nodejs) 为此,首先安装 multer (
npm install multer
)
const multer = require('multer');
const path = require('path')
const storage = multer.diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
cb(null, (new Date()).getTime().toString() + ".jpg");
},
});
const fileFilter = (req, file, cb) => {
if (file.mimetype == "image/jpeg" || file.mimetype == "image/png") {
cb(null, true);
} else {
cb(null, false);
}
};
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 6,
},
fileFilter: fileFilter,
});
最后,满足flutter应用程序的请求: (在 router.js 中)
router.post('/upload', upload.single("img"), function (req, res) {
console.log("hit")
console.log(req.body._id)
res.send("ok")
})
这个方法对我来说很有效,而且我发现它比其他方法更容易。
导入dio,
image_picker
库
Future _onGalleryPressed() async {
Future<File> image = ImagePicker.pickImage(source: ImageSource.gallery);
setState(() {
this._imageFile = image;
});
File img = await image;
Navigator.of(context).pop();
if (img != null) {
//API CALL
try {
FormData formData = new FormData.from({"file": path});
var url = backendUrl + "/upload-image";
var token = await _getMobileToken();
Map<String, String> headers = {
'Authorization': 'Bearer $token',
"Content-Type": "multipart/form-data",
"X-Requested-With": "XMLHttpRequest"
};
await dio.post(url,
data: formData,
options: Options(
method: 'POST',
headers: headers,
responseType: ResponseType.json // or ResponseType.JSON
));
Navigator.pop(context);
} catch (e) {}
}
}
如果您想将其作为二进制文件上传。
static uploadFile(File imageFile) async {
final response = await http.post(postURL, body: imageFile.readAsBytesSync());
return json.decode(response.body);
}
谢谢你
我查了很多地方终于找到了解决方案 -
var objToSend = {
"file": await MultipartFile.fromFile(
file.path,
filename: filename,
),
};
FormData formData = FormData.fromMap(objToSend);
print(formData.files.toString());
Dio dio = new Dio();
await dio
.post(_toSend,
data: formData,
options: Options(
method: 'POST',
headers: <String, String>{
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Authorization": 'Bearer ' + token
},
))
.whenComplete(() {
print('uploaded');
}).catchError((onError) {
print('failed');
});
const express = require('express');
const mongoose = require('mongoose');
const multer = require('multer');
const app = express();
const port = 3000;
// MongoDB connection
mongoose.connect('mongodb://localhost:27017/yourdb', {
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(() => {
console.log('Connected to MongoDB');
}).catch((err) => {
console.error('MongoDB connection error:', err);
});
// Define Image Schema
const imageSchema = new mongoose.Schema({
imageData: Buffer,
contentType: String,
});
const Image = mongoose.model('Image', imageSchema);
// Setup multer storage (store image in memory)
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
// POST route to upload image
app.post('/upload', upload.single('image'), async (req, res) => {
try {
const newImage = new Image({
imageData: req.file.buffer,
contentType: req.file.mimetype,
});
// Save the image to MongoDB
await newImage.save();
res.status(200).send('Image uploaded successfully');
} catch (error) {
res.status(500).send('Failed to store image');
}
});
// Start the server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Image Upload',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ImageUploadPage(),
);
}
}
class ImageUploadPage extends StatefulWidget {
@override
_ImageUploadPageState createState() => _ImageUploadPageState();
}
class _ImageUploadPageState extends State<ImageUploadPage> {
final ImagePicker _picker = ImagePicker();
// Variable to store picked image
XFile? _image;
// Function to pick an image
Future<void> _pickImage() async {
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
if (image != null) {
setState(() {
_image = image;
});
}
}
// Function to upload image to Node.js server
Future<void> _uploadImage() async {
if (_image == null) return;
final bytes = await _image!.readAsBytes();
final uri = Uri.parse('http://192.168.1.5:3000/upload'); // Change to your server's local IP
// Prepare the multipart request
final request = http.MultipartRequest('POST', uri)
..files.add(http.MultipartFile.fromBytes(
'image',
bytes,
filename: 'image.jpg',
contentType: MediaType('image', 'jpeg'), // Correct mime type for JPEG images
));
try {
final response = await request.send();
if (response.statusCode == 200) {
print('Image uploaded successfully');
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Image uploaded successfully')));
} else {
print('Image upload failed: ${response.statusCode}');
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Image upload failed')));
}
} catch (e) {
print('Error: $e');
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error uploading image')));
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Upload'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_image != null)
Image.file(File(_image!.path), height: 200, width: 200),
SizedBox(height: 20),
ElevatedButton(
onPressed: _pickImage,
child: Text('Pick Image'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _uploadImage,
child: Text('Upload Image'),
),
],
),
),
);
}
}