I'm trying to make a api call but I can't success, everything goes fine until the call, and there stop everything and the function finish, what I do wrong?
Future<String> get() async {
var url = Uri.parse("https://10.0.2.2:7021/api/Auth/login");
var headers = {"content-type": "application/json"};
final msg = jsonEncode(
{"username": "string", "password": "string", "email": "string"});
var response = await http!.post(url, body: msg, headers: headers);
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
print("Correct");
return "Correct";
} else {
print(response.statusCode);
print("User not allowed");
throw Exception("User not allowed");
}
}
Mistake comes here
debug window
You have probably imported the "wrong" http. Do it like that:
import 'package:http/http.dart' as http;
You dont need to write http! because http is a package and is never null and since you are doing http! I guess you imported something wrong in your code.
EDIT:
Maybe your device can't reach 10.0.2.2 (or that port), you should set a timeout to find it out fast:
http.post(url, body: msg, headers: headers).timeout(
const Duration(seconds: 3),
onTimeout: () {
// request timed out
return http.Response('Error', 408);
},
);
Have you imported http package like this?
import 'package:http/http.dart' as http;
And use case like this
var response = await http.post(url, body: msg, headers: headers);
add .php to login in the url :
https://10.0.2.2:7021/api/Auth/login.php
if you are working with php
or .py for python
Related
I want to create a login method to post http request. I use the following code to post user data into the server and get a response:
import 'dart:convert';
import 'dart:html';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import '../Services/baseHttp.dart' as base;
class Services {
late var token = '';
Future<http.Response> login(String username, String password) async {
var url = base.BaseURL.loginUrl;
Map data = {"username": username, "password": password};
var body = json.encode(data);
var response = await http.post(Uri.parse(url),
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: body);
print(response.statusCode);
token = response.body;
print(token);
return response;
}
}
I tried to use try catch inside the method:
Future<http.Response> login(String username, String password) async {
try {
var url = base.BaseURL.loginUrl;
Map data = {"username": username, "password": password};
var body = json.encode(data);
var response = await http.post(Uri.parse(url),
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: body);
print(response.statusCode);
token = response.body;
print(token);
return response;
} catch (e) {
print(e);
}
}
I want to send statusCode instead of print(e) when any exception is thrown. How can I do that?
To check whether a response is valid, you can check the status code if it's equal to 200 like this:
if (response.statusCode == 200){
// Do something
} else {
// Throw exception
}
Taking a look the official documentation. You will see the following:
Future<Album> fetchAlbum() async {
final response = await http
.get(Uri.parse('https://jsonplaceholder.typicode.com/albums/1'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Album.fromJson(jsonDecode(response.body));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load album');
}
}
The open api request I'm trying to use requires an image binary value with content-type of multipart/form-data format.
I know you can't use dart:io in flutter web. I tried to upload an image in multipart/form-data format to the api server in flutter web while looking at several posts.
However, only a message appeared stating that the image could not be recognized.
This is the last thing I tried to create multipart types in flutter web.
import 'package:dio/dio.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
PlatformFile? objFile;
pickImage() async {
var result = await FilePicker.platform.pickFiles(
withReadStream: true,
);
setState(() {
objFile = result!.files.single;
});
uploadImage();
}
uploadImage() async {
FormData formData = FormData.fromMap({'image' : MultipartFile(test!, objFile!.size, filename: objFile!.name)});
Dio dio = new Dio();
var response = await dio.post('API url', data: formData);
}
I additionally used Multipart.form Bytes from http , Multipart.form Bytes from dio . But the result was the same.
The value checked by the request body through the postman interceptor.
content-type=multipart/form-data;bounary=--dio-boundary-1105759322
----dio-boundary-1105759322
content-disposition: form-data; name="image"; filename="test.jpeg"
content-type: application/octet-stream
ÿØÿÛC
%# , #&')*)-0-(0%()(ÿÛC
(((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀŽv"ÿÄÿÄC!1AQaq"‘2¡±#BÁÑR3CðñSbr’á‚Â$&4c“ÿÄÿÄ&!1A2Q"a3BRÿÚ?ù× „É<$/cŸt8D`aú¦Ä#bálŒZVM„ٔʓTL›eOò¢“
èKÇ(p¢‰¥C’ÄÙ‚Ñx²Ù1Jcœ)B›¢$ ¢‚&
‚7› ˜Žp”{&ÊÀÁAî¤Æ
‚nÈ CØÃêOýÒ›§á$sÊ‚r¡ìLÂ…;"éMI½î«gæV<æ6οÙ%_ƒY®}7Òû€¯MŒ&g¹å|µ£ëÐúc\tÚƵƈúÕ]#kQ‹D/Ÿú·cu9«Hà/¢lÚ–êè·¼&Þt
¯H‚&ɶìÛà®iƒh²SöãÔTs[l›/?[s(’˜¨o€¤Û‹*¥AÖ”ðbUgYR’!äJ!M‹™‹«›î©aÉ*ᕨ4p SÉ…¤)‰ì§=‘âJ» oÙGDRåÌy0—²û r ò€·²?Te8±KSTR8ŹDAååþ7)Oˆk)õ²Qk#Ù€Œ ?DÜû&Ä›„ÍÅ”lQjð¡NÑ%HTWP˜²wýÒc(Ÿð¤ð¢S<*6º>ÊaCœ „Ù0
^J(ª%¢ƒFPm‘^u4^èM‘åL…##•0Qÿ ºi…32§ÙC•D¿&Èw’ˆº‘Ü"…”<&ýРwP {p ¸DCd¼&ÿ©#¨ˆ› La~¨p¦„)’÷‚ˆº²æÒ›ªĘ̀Šaá€0‹n <ò¦M“YM„ L«=ÕnæÊlªŽÂƒóc„m‚—È™Uó ªºäªÛ•F†\…}7?¨ªZL`*£è¾ŽÝÌ1¤ÜBúk6
---------------------------SKIP------------------------------
PTiMÂ!¢(èÊ€YÊÂœ"ÑÂ_T<Ñ5îPp™ð ¨„ôOˤ?¢z\ÂÚ¡½ÐiÊc쨟ÝHŸ¢“3ÝA˜( ‘ÊH›(l€Å¼)Ä‘rEÈ[€‹¬”¼x
W7q?ΣHt®“§¤y\½Ìÿ:ÿÍtÖ§T°AÊÕ\ËZVƒÔPha30%1*¶›Ž!7è¥|f›„îÕQ±„9N6åW,¨^Ù8PHN./Ê€îª2ß*{(l¡™šOU¢Ôå3œ*ꜨŠ‹“3¼$«B*ÌŒS„+EÒ‘Ý VHpV±`²³ó€µgܪ‚#“Ü)À!NPCƒÝIÅԛ–”xý”²™# ?U‚‹n€å!Œ¦&é*ƒ™¨wÄÖØY¢>«}&ü¢×\Ý?ó*9ç%Òº˜#çò H€¥&ꃒ¤(
‚0O8##EÎéÊœ#TÕr‚ºT¹ÈÔ7T“2¢ƒœbÅsuOî¶Ô0>‹ŸT|Gô•Óa®ïšÔÇe¤T
he<,¨[ü¶[…·M#ZOˆjtˤÝE© QÿÙ
----dio-boundary-1105759322--
When I use the MultipartFile.fromFile method used in flutter ios, I got the response normally. So I'm pretty sure there must be some mistake or misinformation in the flutter web setup.
Thanks in advance!
this is how I managed to upload an image to Laravel backend using Flutter Web
import 'dart:io';
import 'package:dio/dio.dart' as dio;
import 'package:file_picker/file_picker.dart';
Future pickupUserImage2() async {
PlatformFile? objFile;
var picked = await FilePicker.platform.pickFiles();
objFile = picked!.files.single;
String? apiUrl = Get.find<MainController>().apiUrl;
String url = '';
if (apiUrl != null) url = apiUrl + 'images';
List<int> list;
list = List<int>.from(objFile.bytes!);
dio.FormData formData = dio.FormData.fromMap({'file': dio.MultipartFile.fromBytes(list, filename: objFile.name)});
DioNetworking _dio = new DioNetworking();
dynamic result = await _dio.postData(
url,
formData,
contentType: 'multipart/form-data',
);
if (result['status'] == true) {
showToast(result['message']);
return ImageModel.Image.fromJson(result['data']);
}
}
I added a file using MultipartFile.fromBytes which has the first parameter as List which I created from this method "List.from(objFile.bytes!);"
Notes :
ImageModel.Image is a model I created to handle the image result
DioNetworking is a class that perform dio requests , I just created it to do the
authentication stuff
import 'package:dio/dio.dart';
class DioNetworking {
Dio _dio = new Dio();
Future postData(
String url,
dynamic data, {
String? contentType,
}) async {
try {
Response response = await _dio.post(url,
data: data,
options: Options(headers: {
'content-type': contentType != null ? contentType : 'application/json',
'Accept': 'application/json',
// 'Authorization': 'Bearer ${token ?? ''}'
// other headers
}));
if (response.statusCode == 200) {
dynamic data = response.data;
return data;
} else {
print(response.statusCode);
}
} on DioError catch (e) {
print(e);
if (e.type == DioErrorType.connectTimeout) {
return {'status': 'Connect Timed Out'};
}
if (e.type == DioErrorType.receiveTimeout) {
return {'status': 'Receive Timed Out'};
}
if (e.type == DioErrorType.response) {
print(e.response!.data);
print(e.response!.headers);
}
}
}
}
I'm trying to log in on this forum, I tried several ways (Dio, Requests ) without result.
I tested it with postman using other languages and libraries (like curl, python, node) and it works like a charm.
[EDIT]
Ok finally got it!
once logged in, the server returns the status code 303.
and since followredirects is set to true by default, a new request was made without session cookies.
That's why I never found the session cookie in the response header.
A method similar to "history" from lib python requests would be great here.
new:
import 'package:http/http.dart';
void main() async {
final request = new Request(
'POST', Uri.parse('https://xenforo.com/community/login/login'))
..headers.addAll({"Content-Type": "application/x-www-form-urlencoded"})
..bodyFields = {'login':'myuser',
'password': 'mypass'}
..followRedirects = false; // don't follow the damn 303 code if you're not
// going to set the cookies automatically.
final response = await request.send();
print(response.statusCode); // 303 redirected successfully logged in!
print(response.headers); // session token: xf_session=oisufhisuefhsef...
}
or
import 'dart:io';
void main() async {
final client = HttpClient();
final request = await
client.postUrl(Uri.parse("https://xenforo.com/community/login/login"));
request.headers.set(HttpHeaders.contentTypeHeader, "application/x-www_form-urlencoded");
request.followRedirects = false;
request.write("login=myusername&password=mypass");
final response = await request.close();
print(response.statusCode);
print(response.headers);
}
You should either use await or then, try the following code:
import 'package:http/http.dart' as http;
void main() {
http.get("https://xenforo.com/community/").then((response) {
var ls = response.headers['set-cookie'].split(';');
final cookie = ls[0] + '; ' + ls[5].split(',')[1];
login(cookie);
});
}
void login(String cookie) {
http.post("https://xenforo.com/community/login/login/", headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': cookie
}, body: {
'login': 'myusernam',
'password': 'mypass'
}).then((response) {
print(response.statusCode);
print(response.body);
});
}
ok finally got it Every time the login was successful, the request was automatically redirected without the session cookies. FollowRedirects need set to false to work properly and http.post does not have this option.
A method similar to the "history" of lib python requests would be great.
Suppose the host site is: :
https://dev.xyz.com
API header key: "x-api-key: 7462-3172-8773-3312-5819"
To register a new user you have to call PUT method: {{host}}/api/customer/
And the body is like this:
{"email": "test#example.net",
"password": "aabbccdd",
"Name": "John",
}
Now how do I accomplish this in flutter? I have searched through several tutorials and still in confusion.
Import the http package from dart library and alias it as http, reason for this aliasing is that you dont want to have .get() method suggestion everywhere in the file. So when you use it with http as http.get() it will give you suggestion for get, In which you can pass the parameter called headers.
Code goes as follows:
import 'package:http/http.dart' as http;
url = 'YOUR_URL';
var response = await http.get(
url,
headers: {HttpHeaders.authorizationHeader: TOKEN}, //an example header
);
In your case,
import 'dart:convert';
import 'dart:io';
import 'dart:async';
main() async {
String url =
'https://dev.xyz.com';
Map map = {
'data': {'apikey': '7462-3172-8773-3312-5819'},
};
print(await apiRequest(url, map));
}
Future<String> apiRequest(String url, Map jsonMap) async {
HttpClient httpClient = new HttpClient();
HttpClientRequest request = await httpClient.postUrl(Uri.parse(url));
request.headers.set('content-type', 'application/json');
request.add(utf8.encode(json.encode(jsonMap)));
HttpClientResponse response = await request.close();
// todo - you should check the response.statusCode
String reply = await response.transform(utf8.decoder).join();
httpClient.close();
return reply;
}
You need put the header on the http request. For example:
await put(urlApi + 'update/'+ customer.id, headers: {'token': token, 'content-type': 'application/json'},body: body);
I have a login page where i am trying to send a login request to my backend. But I get an Unhandled Exception: Invalid header field name. Here is my submit function
submit() async {
var res = await LoginAPI().loginData(
{'email': _emailController.value, 'password': _passwordController.value});
var body = json.decode(res.body);
print(body);
}
Then in my LoginAPI class here is my loginData function that makes the call to the backend
import 'dart:convert';
import 'package:http/http.dart' as http;
class LoginAPI {
final String _url = "http://10.0.2.2:8000/api/";
Map<String, String> headers = {"Content-type": "application/json"};
loginData(data) async {
var fullUrl = _url + "v1/users/login";
return await http.post(
fullUrl,
body: jsonEncode(data),
headers: headers
);
}
}
Here is my request through postman
Here is my response through postman
When I make the same request with Postman i get the response I am supposed to get. What Am i doing wrong?
try this
Map<String, String> headers = {"Content-type": "application/json", "Accept": "application/json",};
It looks from your postman request that you are just sending form data (not a json encoded body). package:http will form encode the body for you (and add the content type header) if you do the following:
return await http.post(
fullUrl,
body: data,
);
So i was able to solve the issue. The issue was with my CORS middleware on my server. I just made some changes and it worked fine. So if anyone has this issue just know it has nothing to do with flutter but most probably CORS