I'm trying to do a http post request and I need to specify the body as form-data, because the server don't take the request as raw or params.
here is the code I tried
** Future getApiResponse(url) async {
try {
// fetching data from the url
final response = await http.get(Uri.parse(url));
// checking status codes.
if (response.statusCode == 200 || response.statusCode == 201) {
responseJson = jsonDecode(response.body);
// log('$responseJson');
}
// debugPrint(response.body.toString());
} on SocketException {
throw FetchDataException(message: 'No internet connection');
}
return responseJson;
}
}
but its not working. here is the post man request
enter image description here
its not working on parms. only in body. its because this is in form data I guess.
how do I call form data in flutter using HTTP post?
First of all you can't send request body with GET request (you have to use POST/PUT etc.) and you can use Map for request body as form data because body in http package only has 3 types: String, List or Map. Try like this:
var formDataMap = Map<String, dynamic>();
formDataMap['username'] = 'username';
formDataMap['password'] = 'password';
final response = await http.post(
Uri.parse('http/url/of/your/api'),
body: formDataMap,
);
log(response.body);
For HTTP you can try this way
final uri = 'yourURL';
var map = new Map<String, dynamic>();
map['device-type'] = 'Android';
map['username'] = 'John';
map['password'] = '123456';
http.Response response = await http.post(
uri,
body: map,
);
I have use dio: ^4.0.6 to create FormData and API Calling.
//Create Formdata
formData = FormData.fromMap({
"username" : "John",
"password" : "123456",
"device-type" : "Android"
});
//API Call
final response = await (_dio.post(
yourURL,
data: formData,
cancelToken: cancelToken ?? _cancelToken,
options: options,
))
I am currently working on a mobile app and I am stuck in this for days now. I have been trying to send a post request to create an object "Leave" as represents the code below. The request body is formData with a key 'leave' and value 'jsonObject'.I've tried a lot of methods and it has a relation with 'Content-type'I suppose. If i change it to 'multipart/form-data' the response becomes 500 and if it is 'application/json' i always get 415 unsupported mediaType. This is my code using dio package, any advice would be helpful guys, thank u on advance.Postman request works fine
Future createLeave() async {
var leave = Conge(
dateDemand: DateTime.now(),
dateEnd: DateTime.now().add(Duration(days: 3)),
dateStart: DateTime.now().add(Duration(days: 1)),
type: "CSS",
endDateDaySlot: "X",
startDateDaySlot: "X",
);
Map<String, String> heads = {
"X-Auth-Token": UserPreferences().token,
"Content-type": 'application/json',
"accept": "application/json"
};
FormData formData = FormData.fromMap({"leave": leave.toJson()});
var dio = Dio();
try {
Response response = await dio.post(API + '/leave/add',
data: formData,
options:
Options(headers: heads, contentType: Headers.jsonContentType));
} on Exception catch (e) {
print(e);
}
}
I have also tried to use MultiPartRequest but i always get 400 as a response, the request sent by the client was syntactically incorrect here is my code could anyone help me with this please
Future create(Conge leave) async {
String url = API + "/leave/add";
var uri = Uri.parse(url);
var request = new http.MultipartRequest("POST", uri);
Map<String, String> heads = {
"X-Auth-Token": UserPreferences().token,
"Content-type": 'application/json',
};
request.headers.addAll(heads);
request.fields['leave'] = json.encode(leave.toJson());
var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}
Please try to disable the firewall of windows, if it works then make an exception for it in the firewall.
I use a web service for image processing , it works well in Postman:
Now I want to make http request in flutter with Dart:
import 'package:http/http.dart' as http;
static ocr(File image) async {
var url = '${API_URL}ocr';
var bytes = image.readAsBytesSync();
var response = await http.post(
url,
headers:{ "Content-Type":"multipart/form-data" } ,
body: { "lang":"fas" , "image":bytes},
encoding: Encoding.getByName("utf-8")
);
return response.body;
}
but I don't know how to upload the image file, in above code I get exception: Bad state: Cannot set the body fields of a Request with content-type "multipart/form-data".
How should I write the body of request?
Your workaround should work; many servers will accept application/x-www-form-urlencoded as an alternative (although data is encoded moderately inefficiently).
However, it is possible to use dart:http to do this. Instead of using http.post, you'll want to use a http.MultipartFile object.
From the dart documentation:
var request = new http.MultipartRequest("POST", url);
request.fields['user'] = 'someone#somewhere.com';
request.files.add(http.MultipartFile.fromPath(
'package',
'build/package.tar.gz',
contentType: new MediaType('application', 'x-tar'),
));
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
I'd like to recommend dio package to you , dio is a powerful Http client for Dart/Flutter, which supports Interceptors, FormData, Request Cancellation, File Downloading, Timeout etc.
dio is very easy to use, in this case you can:
Sending FormData:
FormData formData = new FormData.from({
"name": "wendux",
"file1": new UploadFileInfo(new File("./upload.jpg"), "upload1.jpg")
});
response = await dio.post("/info", data: formData)
More details please refer to dioγ
This can be achieved using the MultipartRequest class (https://pub.dev/documentation/http/latest/http/MultipartRequest-class.html)
Change the media type and uri as needed.
uploadFile() async {
var postUri = Uri.parse("<APIUrl>");
var request = new http.MultipartRequest("POST", postUri);
request.fields['user'] = 'blah';
request.files.add(new http.MultipartFile.fromBytes('file', await File.fromUri("<path/to/file>").readAsBytes(), contentType: new MediaType('image', 'jpeg')))
request.send().then((response) {
if (response.statusCode == 200) print("Uploaded!");
});
}
I found a working example without using any external plugin , this only uses
import 'package:http/http.dart' as http;
import 'dart:io';
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:convert';
Code
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);
});
How to upload image file using restAPI in flutter/dart.
This work for me.
var postUri = Uri.parse("apiUrl");
http.MultipartRequest request = new http.MultipartRequest("POST", postUri);
http.MultipartFile multipartFile = await http.MultipartFile.fromPath(
'file', filePath);
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
print(response.statusCode);
Updated 2021 way:
using flutter http and mime
import 'package:mime/mime.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'dart:io';
Future<dynamic> multipartImageUpload(String baseUrl, String api, File image) async {
var uri = Uri.parse(baseUrl + api);
final mimeTypeData =
lookupMimeType(image.path, headerBytes: [0xFF, 0xD8]).split('/');
// Intilize the multipart request
final imageUploadRequest = http.MultipartRequest('PUT', uri);
// Attach the file in the request
final file = await http.MultipartFile.fromPath('image', image.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
imageUploadRequest.files.add(file);
// add headers if needed
//imageUploadRequest.headers.addAll(<some-headers>);
try {
final streamedResponse = await imageUploadRequest.send();
final response = await http.Response.fromStream(streamedResponse);
return response;
} catch (e) {
print(e);
return null;
}
}
Use MultipartRequest class.
How to upload image file using restAPI in flutter/dart
void uploadImage1(File _image) async {
// open a byteStream
var stream = new http.ByteStream(DelegatingStream.typed(_image.openRead()));
// get file length
var length = await _image.length();
// string to uri
var uri = Uri.parse("enter here upload URL");
// create multipart request
var request = new http.MultipartRequest("POST", uri);
// if you need more parameters to parse, add those like this. i added "user_id". here this "user_id" is a key of the API request
request.fields["user_id"] = "text";
// multipart that takes file.. here this "image_file" is a key of the API request
var multipartFile = new http.MultipartFile('image_file', stream, length, filename: basename(_image.path));
// add file to multipart
request.files.add(multipartFile);
// send request to upload image
await request.send().then((response) async {
// listen for response
response.stream.transform(utf8.decoder).listen((value) {
print(value);
});
}).catchError((e) {
print(e);
});
}
name spaces:
import 'package:path/path.dart';
import 'package:async/async.dart';
import 'dart:io';
import 'package:http/http.dart' as http;
UPLOAD IMAGE TO SERVER WITH FORM DATA
To upload image to server you need a dio library.
Features:
Authorization (adding token)
Adding extra field like: username, etc
Adding Image to upload
Code example:
import 'package:dio/dio.dart' as dio;
import 'dart:convert';
try {
///[1] CREATING INSTANCE
var dioRequest = dio.Dio();
dioRequest.options.baseUrl = '<YOUR-URL>';
//[2] ADDING TOKEN
dioRequest.options.headers = {
'Authorization': '<IF-YOU-NEED-ADD-TOKEN-HERE>',
'Content-Type': 'application/x-www-form-urlencoded'
};
//[3] ADDING EXTRA INFO
var formData =
new dio.FormData.fromMap({'<SOME-EXTRA-FIELD>': 'username-forexample'});
//[4] ADD IMAGE TO UPLOAD
var file = await dio.MultipartFile.fromFile(image.path,
filename: basename(image.path),
contentType: MediaType("image", basename(image.path)));
formData.files.add(MapEntry('photo', file));
//[5] SEND TO SERVER
var response = await dioRequest.post(
url,
data: formData,
);
final result = json.decode(response.toString())['result'];
} catch (err) {
print('ERROR $err');
}
To add a header and use http multipart with https://pub.dev/packages/multi_image_picker Plugin,
This is the code.
var request = http.MultipartRequest(
'POST', Uri.parse(myurl)
);
//Header....
request.headers['Authorization'] ='bearer $authorizationToken';
request.fields['PropertyName'] = propertyName;
request.fields['Country'] = country.toString();
request.fields['Description'] = des;
request.fields['State'] = state.toString();
request.files.add(http.MultipartFile.fromBytes(
'ImagePaths',
learnImage,
filename: 'some-file-name.jpg',
contentType: MediaType("image", "jpg"),
)
);
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
print(res.body);
To use HTTP and https://pub.dev/packages/image_picker PLUGIN
This is the code
var request = http.MultipartRequest(
'POST', Uri.parse(myurl)
);
request.headers['Authorization'] ='bearer $authorizationToken';
request.fields['PropertyName'] = propertyName;
request.fields['Country'] = country.toString();
request.fields['Description'] = des;
request.fields['State'] = state.toString();
request.files.add(await http.MultipartFile.fromPath(
'ImagePaths',
file.path
)
);
var response = await request.send();
print(response.stream);
print(response.statusCode);
final res = await http.Response.fromStream(response);
print(res.body);
Working Code
String path = userSelectedImagePath;
Map<String, String> data = {
"name": firstName!,
"email": userEmail!
};
String token = await LocaldbHelper().getToken();
Map<String, String> headers = {
'X-Requested-With': 'XMLHttpRequest',
'authorization': 'Bearer $token',
};
var request = http.MultipartRequest(
'POST',
Uri.parse(ApiUrl.updateProfile),
);
request.fields.addAll(data);
request.headers.addAll(headers);
var multipartFile = await http.MultipartFile.fromPath(
'avatar', path); //returns a Future<MultipartFile>
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
final respStr = await response.stream.bytesToString();
var jsonData = jsonDecode(respStr);
if (response.statusCode == 200) {
// success
} else {
// error
}
Just leaving this here, if anyone is trying to upload a pdf or any other document using MultipartRequest method.
Just add the content type as -
contentType: new MediaType('application', 'pdf')
Good code with Dio and FilePicker for post file on your server. I use flutter for the web.
FilePicker
Dio
First you need writing Dio post method.
Future postImportClient(PlatformFile file) async {
try {
var urlBase = 'your url';
var mfile = MultipartFile.fromBytes(file.bytes!, filename: file.name);
var formData = FormData();
formData.files.add(MapEntry('file', mfile));
await _dio.post(urlBase, data: formData);
} on DioError catch (error) {
throw Exception(error);
}
}
Initial FilePicker and get file.
FilePickerResult? result = await FilePickerWeb.platform.pickFiles();
if (result != null) {
var file = result.files.single;
await client.postImportClient(file);
}
Good luck!
create FormData:
final formDataMap = <String, dynamic>{};
formDataMap["stringKey"] = "string";
List<MultipartFile> multipartImageList = [];
await Future.forEach(imagePaths as List<String>,(String path) async {
final multiPartFile = await MultipartFile.fromFile(
path,
contentType: MediaType("image", "jpeg"),
);
multipartImageList.add(multiPartFile);
});
formDataMap["image[]"] = multipartImageList;
final formData = FormData.fromMap(formDataMap);
With Retrofit & Dio:
#MultiPart()
#POST("{{url}}")
Future<dynamic> uploadFormData(
#Body() FormData formData,
);
With Hearder
upload image
Future uploadImageMedia(File fileImage, String token) async {
final mimeTypeData =
lookupMimeType(fileImage.path, headerBytes: [0xFF, 0xD8]).split('/');
final imageUploadRequest =
http.MultipartRequest('POST', Uri.parse(mainUrlSite + "wp-json/wp/v2/media"));
final file = await http.MultipartFile.fromPath('file', fileImage.path,
contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
imageUploadRequest.files.add(file);
imageUploadRequest.headers.addAll({
"Authorization": "Bearer " + token
});
try {
final streamedResponse = await imageUploadRequest.send();
streamedResponse.stream.transform(utf8.decoder).listen((value) {
print(value);
return Future.value(value);
});
} catch (e) {
print(e);
}
}
I use Dio library with put method:
var formData = FormData.fromMap({
'simpleParam': 'example',
'file': await MultipartFile.fromFile(filePath, filename: 'file.jpg')
});
var dio = Dio();
dio.options.headers[HttpHeaders.authorizationHeader] = myToken;
var response = new Response(); //Response from Dio
response = await dio.put(myUrl + "/myApi", data: formData);
The result is in response.data
try {
result[HttpKeys.status] = false;
var request = http.MultipartRequest('POST', url);
request.fields.addAll(body);
if (avatar.path.isNotEmpty) {
request.files.add(await http.MultipartFile.fromPath('uploadedImg', avatar.path));
}
request.headers.addAll(headers);
http.StreamedResponse streamResponse = await request.send();
final response = await http.Response.fromStream(streamResponse);
if (response.statusCode == 200) {
var resMap = jsonDecode(response.body);
debugPrint('<== ππππ π¦π‘ π€π¦ππππ€π€ππ¦πππͺ ==>');
// debugPrint(response.body);
result[HttpKeys.status] = true;
result[HttpKeys.message] = resMap[HttpKeys.message];
result[HttpKeys.data] = resMap['data'];
return result;
} else {
var resMap = jsonDecode(response.body);
result[HttpKeys.message] = resMap[HttpKeys.message];
return result;
}
} catch (error) {
result[HttpKeys.message] = error.toString();
return result;
}
Here is the code where I am passing Image, route which may be like '/register', and data which is Map<String, String> like data={'directory':'profile'}.
For Uploading Image to Laravel API, Authorization in header is compulsory otherwise it would return "You don't have permission to access this resource". I am passing token as EMPTY string like String token='' as I am uploading
Image at user registration time
This Authorization for read and write is defined in domainurl/public/.htaccess file, you can change it
Try to understand the below code and all the issue would be resolve.
Future uploadImage({
required XFile file,
required String route,
required Map<String, String> data,
}) async {
String url = API_Url + route;
final uri = Uri.parse(url);
try {
http.MultipartRequest request = http.MultipartRequest("POST", uri);
http.MultipartFile multipartFile =
await http.MultipartFile.fromPath('image', file.path);
request.files.add(multipartFile);
request.headers.addAll(_header());
request.fields.addAll(data);
var streamedResponse = await request.send();
var response = await http.Response.fromStream(streamedResponse);
print(jsonDecode(response.body));
return jsonDecode(response.body);
} catch (e) {
return null;
}
}
_header() {
return {"Content-Type": "multipart/form-data",
'Authorization': 'Bearer ${token}',
};
}
With dio I do like this:
Future<void> _uploadFileAsFormData(String path) async {
try {
final dio = Dio();
dio.options.headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
final file =
await MultipartFile.fromFile(path, filename: 'test_file');
final formData = FormData.fromMap({'file': file}); // 'file' - this is an api key, can be different
final response = await dio.put( // or dio.post
uploadFileUrlAsString,
data: formData,
);
} catch (err) {
print('uploading error: $err');
}
}