I want to send data as FormData to the server but unable to find any way in the Flutter. No doubt flutter supports form data type but how to implement.
Thanks
This link can help you
https://pub.dev/documentation/http/latest/http/MultipartRequest-class.html
Or, in one of my projects I used the following code
var request = new http.MultipartRequest("POST", Uri.parse('http://...'));
Map<String, String> headers = {"Authorization": 'Bearer $token'};//<-- create header
request.headers.addAll(headers); // <-- add header
if (imageFile != null) { //<-- add file (File imageFile)
var stream = new http.ByteStream(imageFile.openRead());
var length = await imageFile.length();
var multipartFile = new http.MultipartFile('FileUplod', stream, length,
filename: basename(imageFile.path));
request.files.add(multipartFile);
}
request.fields['title'] = 'title'; //<--add text item
request.fields['id'] = '12225';
var response = await httpFromData(request);
var responses = await http.Response.fromStream(response);
//json.decode(responses.body) <-- for decode request body if needed
Related
According to node.js Documentation encoding : null when binary data to be sent via Api,
https://www.npmjs.com/package/request in this link below mentioned explanation is found.
encoding - encoding to be used on setEncoding of response data. If
null, the body is returned as a Buffer. Anything else (including the
default value of undefined) will be passed as the encoding parameter
to toString() (meaning this is effectively utf8 by default).
Note: if you expect binary data, you should set encoding: null.
Now I have achieve the same thing in flutter/dart and this encoding parameter is not accepting null as here in node.js they have mentioned.
I want to know how to make this same Post request from Flutter/dart or at least android/java.
var enc = AESCrypt.encrypt(key, iv, JSON.stringify(obj_j));
var output = new Buffer.from(enc, 'hex'); // Buffer
function test() {
console.time("XXX");
request.post({
headers: {
'content-type': 'application/json'
}, //required, or webserver will ignore it application/json multipart/form-data
url: 'http://192.168.29.210/deviceid/read', // webserver url
encoding:null,
body: output
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.timeEnd("XXX");
body = AESCrypt.decrypt(key, iv, body);
//body is decrypted http response, can be parsed with json method
fs.writeFile('input.json', body, function (err) {
if (err) {
return console.error(err);
}
});
}
});
};
Adding code the What i have tried in flutter
var headers = {'Content-Type': 'application/json'};
var request =
http.Request('POST', Uri.parse('http://192.168.29.210/deviceid/read'));
request.body = encryptedText;
request.encoding = null ; // here this null parameter is not acceptable
request.encoding = Encoding.getByName("utf-8")); // only this option is available to add in flutter
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
Even in post man this encoding variable is not present to set it.
Use below flutter framework method
Future<Response> post(Uri url,
{Map<String, String>? headers, Object? body, Encoding? encoding}) =>
_withClient((client) =>
client.post(url, headers: headers, body: body, encoding: encoding));
How to use
final url = Uri.parse('$urlPrefix/posts');
final headers = {"Content-type": "application/json"};
final json = '{"title": "Hello", "body": "body text", "userId": 1}';
final response = await post(url, headers: headers, body: json,encoding:null); //here this null parameter is not acceptable
My Final working code is
var headers = {'Content-Type': 'application/json'};
final response = await http.post(
Uri.parse('http://192.168.29.210/deviceid/read'),
headers: headers,
body: encryptedText,
encoding: null);
if (response.statusCode == 200) {
String res = response.body.toString();
//String data = AesEncryption().decryption(res);
print('Body: ${response.body.toString()}');
} else {
print(response.reasonPhrase);
}
print('Status code: ${response.statusCode}');
I have an application that caters for web, android and ios.
I have implemented the packages below
https://pub.dev/packages/image_picker/example
image_picker: ^0.8.2
image_picker_for_web: ^2.1.1
Tasks:
User needs to select multiple images (When debugging thru android, i sometimes receive websocket connection expection, and application exits without any error message. Bonus if youre able to provide some insights to this issue as well)
Clicks submit to upload the images (XFile) to API
class UserAttachments {
List<XFile>? attachments = [];
int userID = 0;
}
Future<String> submitImage(UserAttachments ua) async {
http.MultipartRequest request =
new http.MultipartRequest("POST", Uri.parse(kAttachmentsURI));
Map<String, String> headers = {"Content-Type": "application/json"};
ua.attachments!.forEach((element) async {
var bytes = element.readAsBytes();
request.files.add(new http.MultipartFile.fromBytes('file', await bytes));
});
request.headers.addAll(headers);
request.fields['userID'] = '23';
http.StreamedResponse responseAttachmentSTR = await request.send();
print(responseAttachmentSTR.statusCode);
return "SENT"; // + " - Respomse: " + map.toString();
}
Above code doesn't seem to work. Any solutions that cater for web/android/ios?
You can't use async on forEach, because that will just return an array of promises and won't wait for them. To fix this, you can use a for loop for asynchronous functions.
for(var i = 0; i < ua.attachments!.length; i++) {
var element = ua.attachments[i];
var bytes = element.readAsBytes();
request.files.add(new http.MultipartFile.fromBytes('file', await bytes));
}
And you can optimize this code using Future.wait
Future<String> submitImage(UserAttachments ua) async {
http.MultipartRequest request =
new http.MultipartRequest("POST", Uri.parse(kAttachmentsURI));
Map<String, String> headers = {"Content-Type": "application/json"};
var bytes = await Future.wait(ua.attachments!.map((el) => el.readAsBytes()));
request.files.addAll(bytes.map((b) => new http.MultipartFile.fromBytes('file', b)));
request.headers.addAll(headers);
request.fields['userID'] = '23';
http.StreamedResponse responseAttachmentSTR = await request.send();
print(responseAttachmentSTR.statusCode);
return "SENT";
}
i using the ImagePicker package in the dart when i pick the image i want to upload this to the server with the form data but when i try to send this i give this error
" Unhandled Exception: FileSystemException: Cannot retrieve length of file, path = 'File: '/storage/emulated/0/Android/data/com.example.aloteb/files/Pictures/scaled_image_picker3594752094355545880.jpg'' "
and this is my code for sending to the server
var request = http.MultipartRequest('POST', Uri.parse(url));
request.fields.addAll({
'data': '$map'
});
request.files.add(await http.MultipartFile.fromPath('image',picproviderformdate.getPAth.toString()));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
and this is my ImagePickercode
picprovider pic = Provider.of<picprovider>(context,listen: false);
File image = await ImagePicker.pickImage(
source: ImageSource.gallery, imageQuality: 50);
setState(() {
_image = image;
});
print(_image);
pic.setpathe(_image);
can any one help me for solve this problem?
I had a similar problem a while ago, and i used the Dio dependency instead of the classical Http link.
The code is very similar, and i can gave you an example.
final File file = File("${documentDirectory.path}/picture.png");
final httpDio = dio.Dio();
final formData = dio.FormData.fromMap({
"data": "{}",
"files.image": await dio.MultipartFile.fromFile(
"${documentDirectory.path}/picture.png",
filename: "picture.png",
contentType: MediaType('image', 'png'))
});
try {
final dio.Response response = await httpDio.post(
"ApiEndpoint/avatars",
data: formData,
options: dio.Options(headers: {"Authorization": "Bearer yourTokenIfNeeded"}));
if (response.statusCode == 200) {
// Success
}
} on dio.DioError catch (e) {
if (e.response != null) {
// Error
print(e.response.data);
return;
}
}
Don't forgot to update the API endpoint and route as well as your auth authorization if you need one.
If I upload over Insomnia an image to my Laravel application everything is ok and I get following log
[2020-03-04 05:26:39] local.DEBUG: array (
'image' =>
Illuminate\Http\UploadedFile::__set_state(array(
'test' => false,
'originalName' => 'Screenshot_1583210368.png',
'mimeType' => 'image/png',
'error' => 0,
'hashName' => NULL,
)),
)
But if I upload an image on android emulator the log file in Laravel looks like (1000+ lines) :
�"#�G����ޠ��U��H��I�G"Ĉ`.SB^G
This is my Xamarin Function :
public async Task<string> uploadImage(Stream stream)
{
using (var client = new HttpClient())
{
var content = new MultipartFormDataContent();
content.Add(new StreamContent(stream),"image");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", (Application.Current.Properties["access_token"].ToString()));
var result = await client.PostAsync("https://example.com/api/upload/image", content);
return "";
}
}
Example of uploading a image to server side in Xamarin:
private MediaFile _image;
// code here to assign image to _image
var content = new MultipartFormDataContent();
content.Add(new StreamContent(_image.GetStream()), "\"file\"", $"\"{_image.Path}\"");
var httpClient = new System.Net.Http.HttpClient();
var url = "http://upload.here.io/folder/subdir";
var responseMsg = await httpClient.PostAsync(url, content);
var remotePath = await responseMsg.Content.ReadAsStringAsync();
I need reference how to use header into the flutter.
I am passing below values for the header .
php-auth-user : test
php-aut-pw : test123
Here is my code for the main.dart
var url = "http:.../public/v1/login";
var body = json.encode({"account_id": "3","email":"saty#xyz.com","password":"admin123"});
this is header which i have used
Map headers = {
'Content-type' : 'application/json',
'php-auth-user':'test'
'php-auth-pw':'test123'
};
final response =
http.post(url, body: body, headers: headers);
final responseJson = json.decode(response.body);
print(responseJson);