How correctly is the request sent from the locale? - flutter

I used strapi to write queries. I checked it on postman, using "localhost" instead of IP, everything is fine. However, when I sent a request from flutter, I got an error, which I managed to avoid by using my ip instead of "localhost". But also through postman now error 502, the same error if sent via flutter
ElevatedButton(onPressed: () async {
var url = 'http://мой.айпи.43/api/pelargoniums';
Map<String,String> headers = {
'Content-Type':'application/json',
'Accept': 'application/json'
};
final response = await http.get(
Uri.parse(url),
headers: headers
);
if (response.statusCode == 200) {
print(response.body);
print('yep');
} else {
print(response.statusCode);
}
}, child: Text('wewewewew'))
Please tell me what is my problem and how to fix it?

When testing on a mobile device (Android , iOS) , you must connect within the same Wi-Fi network to use IP communication. If it is used as a web, Windows, or mac program, it can be used.

Related

How to resolve “Blocked by CORS policy” in a mobile app? NOT A WEB APP

I am trying to use the sales force api. But I keep getting a CORS error. Some try to help by directing me to a solution for a web app that does not work. For example, one link I was directed to says to add the domain to an "allowed" list. But I am not coming from a domain, at least not in any way that I know of. Do all cell phones belong in a domain? Does each phone have its own domain? Or is the solution inapplicable.
Another solution I was criticized for duplication said to use "Access-Control-Request-Method" as described in this post I was directed to. But the first problem is that I had to convert everything from web pass to mobile pass. I have no idea if I did it right. The second problem is that it still fails with no new information. A third problem is the link has absolutely no information what value gets assigned to "Access-Control-Request-Method" I tried various guesses but to no avail.
I have ran out of things to guess!
void getData() async {
var headers = {
'Authorization': 'Bearer access_token',
'Access-Control-Allow-Origin': 'https://instance-name.salesforce.com/',
'Access-Control-Allow-Methods': 'POST, GET',
'Access-Control-Allow-Headers': 'Content-Type, application/json',
};
var res = await http.get(
'https://instance-name.com/services/data/v20.0/',
headers: headers);
if (res.statusCode != 200)
throw Exception('http.get error: statusCode= ${res.statusCode}');
print(res.body);
}
You can use third party service to avoid CORS policy issue. There are several services available online. You can try https://allorigins.win/ and its works fine. Try following code
void getData() async {
var headers = {
'Authorization': 'Bearer access_token',
'Access-Control-Allow-Origin': 'https://instance-name.salesforce.com/',
'Access-Control-Allow-Methods': 'POST, GET',
'Access-Control-Allow-Headers': 'Content-Type, application/json',
};
var res = await http.get(
'https://api.allorigins.win/raw?url=https://instance-name.com/services/data/v20.0',
headers: headers);
if (res.statusCode != 200)
throw Exception('http.get error: statusCode= ${res.statusCode}');
print(res.body);
}

Flutter Http post call Doesn't work on web and works on mobile only

loginUser(email, password) async {
var url = Uri.parse
.call("https://us-central1-agenie-webapp.cloudfunctions.net/api/login");
final http.Response response = await http.post(
url,
headers: <String, String>{
'Content-Type': 'application/json',
},
body: jsonEncode(<String, String>{'email': email, 'password': password}),
);
if (response.statusCode == 200) return response.body;
return null;
}
This is the api post call when I run this on web localhost with flutter run ,when I click on login button that calls this function on pressed it open a window in vscode named browser_client.dart and goes to line 69 where it shows :
unawaited(xhr.onError.first.then((_) {
// Unfortunately, the underlying XMLHttpRequest API doesn't expose any
// specific information about the error itself.
completer.completeError(
ClientException('XMLHttpRequest error.', request.url),
StackTrace.current);
}));
Any solutions ? Thanks
I suggest you trying to use the dio package (https://pub.dev/packages/dio), it worked in my web project.

ClientException in io_client.dart

The code below works started giving trouble when the back-end server is switched from HTTP to HTTPS. The back-end application is written in .NET and runs on IIS 10.0
response = await http.post(
Uri.encodeFull("https://_____________/api/account/login"),
body: json.encode(body),
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
// ignore: missing_return
}).timeout(Duration(seconds: 10), onTimeout: () {
throw ('You seem to be offline');
});
if (response.statusCode == 500) {
.......
See the screenshot below for exact exception. Interestingly, there's no exception message.
The code works well on other HTTPS back-end such as MS Azure hosted APIs. The API call works well in the Postman.
Can anyone help ?
EDIT : Found a related github issue

How to remove Authorization header on redirect on any Flutter/Dart http client

I'm currently working on a project which like a lot of other projects works with s3 storage. In this case the storage is linked via the back-end.
The situation is like this, I can get the 'attachment' via an URL, lets say example.com/api/attachments/{uuid}. If the user is authorized (via the header Authorization) it should return a 302 statuscode and redirect to the s3 url. The problem is that after the redirect the Authorization header persists and the http client return a 400 response and it's because of the persisting Authorization header. Is there any way I can remove the Authorization header after redirect without catching the first request and firing a new one?
My http client code currently looks like this:
#override
Future get({
String url,
Map<String, dynamic> data,
Map<String, String> parameters,
}) async {
await _refreshClient();
try {
final response = await dio.get(
url,
data: json.encode(data),
queryParameters: parameters,
);
return response.data;
} on DioError catch (e) {
throw ServerException(
statusCode: e.response.statusCode,
message: e.response.statusMessage,
);
}
}
Future<void> _refreshClient() async {
final token = await auth.token;
dio.options.baseUrl = config.baseUrl;
dio.options.headers.addAll({
'Authorization': 'Bearer $token',
'Accept': 'application/json',
});
dio.options.contentType = 'application/json';
}
Good news! This has been fixed recently with Dart 2.16 / Flutter v2.10!
Related bugs in dart issue tracker:
https://github.com/dart-lang/sdk/issues/47246
https://github.com/dart-lang/sdk/issues/45410
Official announcement:
https://medium.com/dartlang/dart-2-16-improved-tooling-and-platform-handling-dd87abd6bad1
TLDR: upgrade to Flutter v2.10!
Looking at the Dio docs, it seems like this is intentional behaviour.
All headers added to the request will be added to the redirection request(s). However, any body send with the request will not be part of the redirection request(s).
https://api.flutter.dev/flutter/dart-io/HttpClientRequest/followRedirects.html
However, I understand (and agree!) that this is generally undesirable behaviour. My solution is to manually follow the redirects myself, which is not very nice but works in a pinch.
Response<String> response;
try {
response = await dio.get(
url,
options: Options(
// Your headers here, which might be your auth headers
headers: ...,
// This is the key - avoid following redirects automatically and handle it ourselves
followRedirects: false,
),
);
} on DioError catch (e) {
final initialResponse = e.response;
// You can modify this to understand other kinds of redirects like 301 or 307
if (initialResponse != null && initialResponse.statusCode == 302) {
response = await dio.get(
initialResponse.headers.value("location")!, // We must get a location header if we got a redirect
),
);
} else {
// Rethrow here in all other cases
throw e;
}
}

http.post return 307 error code in flutter

I am using http client for flutter network call.
My request working on postman getting response properly,
But while trying with http.post it returns error code 307-Temporary Redirect,
Method Body:
static Future<http.Response> httpPost(
Map postParam, String serviceURL) async {
Map tempParam = {"id": "username", "pwd": "password"};
var param = json.encode(tempParam);
serviceURL = "http:xxxx/Login/Login";
// temp check
Map<String, String> headers = {
'Content-Type': 'application/json',
'cache-control': 'no-cache',
};
await http.post(serviceURL, headers: headers, body: param).then((response) {
return response;
});
}
Also, the same code returns a proper response to other requests and URLs.
First I trying with chopper client but had same issue.
I am unable to detect that issue from my end of from server-side.
Any help/hint will be helpful
Try to put a slash / at the end of the serviceUrl. So, serviceUrl is serviceURL = "http:xxxx/Login/Login/" instead of serviceURL = "http:xxxx/Login/Login".
This works for me.
You need to find a way to follow redirect.
Maybe postman is doing that.
Read this >>
https://api.flutter.dev/flutter/dart-io/HttpClientRequest/followRedirects.html
Can you try with using get instead of post? At least to try and see what happend
In the documentation said:
Automatic redirect will only happen for "GET" and "HEAD" requests
only for the status codes
HttpStatus.movedPermanently (301),
HttpStatus.found (302),
HttpStatus.movedTemporarily (302, alias for HttpStatus.found),
HttpStatus.seeOther (303),
HttpStatus.temporaryRedirect (307)
keeping https instead of http in the URL it is helping me.
#Abel's answer above is correct but I had to switch from using:
Uri url = Uri.https(defaultUri, path);
to
Uri url = Uri.parse('https://todo-fastapi-flutter.herokuapp.com/plan/');
to get that last / after plan.
The first way kept dropping it so I was getting 307 errors.
flutter.dev shows a full example:
Future<http.Response> createAlbum(String title) {
return http.post(
Uri.parse('https://jsonplaceholder.typicode.com/albums'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'title': title,
}),
);
}
here: https://flutter.dev/docs/cookbook/networking/send-data#2-sending-data-to-server
For Dio Http Client, use Dio Option follow redirect as True
getDioOption(){
return BaseOptions(connectTimeout: 30, receiveTimeout: 30,
followRedirects: true);
}