How to get a cookie in Flutter Web from header? - flutter

The Flutter Web application send a HTTP REST API POST request and gets back a JSON response and a cookie in the Set-Cookie header as follows.
(Flutter (Channel beta, 1.22.0, on Microsoft Windows)
When the cookie is extracted, the response does not seem find the header value. The call and extraction code is:
var response = await http.post(url, headers: {"Content-Type": "application/json"}, body: jsonEncode(data));
if (response.statusCode == 200) {
var cookie = response.headers['set-cookie'];
print('cookie: $cookie');
}
The console result is:
cookie: null
The server side runs on ASPNet.Core 3.1 in a Docker container, however it should not be an issue, since the cookie is there in the header. So, how can I extract it in Flutter Web?
Actually my final goal is to send the cookie back with every other request. But it does not seem to happen automatically in the browser. So it is also a good solution if someone could point out the proper way of handling this scenario.
Any help is appretiated. Thanks.

The question was asked a month ago but my answer might be helpful for someone else.
Cookies in Flutter Web are managed by browser - they are automatically added to requests (to Cookie header), if the cookie was set by Set-Cookie previously - more precisely, it works correctly when you do release build.
In my case it didn't work during dev builds. My solution:
On server set headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:61656
// port number may be different
In flutter:
class member:
final http.Client _client = http.Client();
// example
Future<String> getTestString() async {
if (_client is BrowserClient)
(_client as BrowserClient).withCredentials = true;
await _client.get('https://localhost/api/login');
await _client.get('https://localhost/api/login');
return 'blah';
}
http.Client() creates an IOClient if dart:io is available and a BrowserClient if
dart:html is available - in Flutter Web dart:html is available.
Setting withCredentials to true makes cookies work.
Run your app:
flutter run -d chrome --web-port=61656
// the same port number that on server
Remember that in Flutter Web network requests are made with browser XMLHttpRequest.

Related

Using MultiPartRequest to upload file in flutter web

So im currently trying to send images from file picker to an api that had a file input, here is the postman display and the thing was, i've tried it with numerous way that was in other post, but none of them is working for me, this is the error that i get from my web browser console and this is the code that i've tried to work with:
var postUri = Uri.parse(constanta.getMyid());
http.MultipartRequest request = new http.MultipartRequest("POST", postUri);
http.MultipartFile multipartFile = await http.MultipartFile.fromBytes(
'data', image);
request.files.add(multipartFile);
http.StreamedResponse response = await request.send();
print(response.statusCode);
i don't think the main problem was the CORS, because the api log is indicating that the request is received, but no file was attached to that request.
additional note : i've tried everything from the client side, and i cannot open/edit the backend, because it's a third party api (not owned by me).
As I can see your errors main problem here first is data was rejected from your Server as the server not allowing you to upload files and throw Cross-Origin Access which you have to solve first and then you should try.
If your postman is able to upload images on server that is because postmen itself capable of solving Cross-Origin Acess Error, so here is the solution for the node.js
If your backend is in node js you can inject the below code into your middleware.
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'XMLHttpRequest,Origin,X-Requested-With,Content-Type,Accept,Authorization');
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'PUT,POST,PATCH,DELETE,GET');
return res.status(200).json({});
}
next();
});
Or you can use localhost as a backend server.

Flutter web - dio changes post requests into options requests

I'm using package:dio in a Flutter web application.
Whenever I send a POST request, however, it gets changed into an OPTIONS request. The function that makes the API request looks like this:
Future<LoginResponse> login(LoginRequest request) async {
final dio = Dio(BaseOptions(baseUrl: "http://localhost:8000"));
final response = await dio.post("/login", data: request.toJson());
return LoginResponse.fromJson(jsonDecode(response.data));
}
This code sends an OPTIONS request to http://localhost:8000/login. If I add that endpoint to my server, it works.
If I send the POST request from postman manually it also works.
If I change this code to other methods (e.g. dio.delete(...)) it also maps to an OPTIONS request.
Why is dio rewriting my requests?

How to get custom response headers on web using dio?

I doing a Flutter app and I using dio to connect app with my web service.
When I want to access to custom headers in response, on mobile I don't have any problem, but this headers on web not be available and get different.
My code:
final dio = Dio();
final response = await dio.getUri(requestUri,
options: Options(headers: {
'authorization': 'Bearer ${credentials!.accessToken}',
}));
How I do to on web and mobile get a same custom headers?
This is due to CORS, part of the browser built-in cross-site security restrictions. Your server need to include your custom headers into the "preflight" OPTIONS response header Access-Control-Expose-Headers to allow your browser to see those headers.
For example, https://discuss.istio.io/t/configuring-cors/7458/5

How do I check whether an url link exists and get statusCode in flutter?

I'm trying to check whether an url exists by using statusCode == 200 but when I try to use await http.get(url), it didn't work. I got this error XMLHttpRequest error
flutter version
2.5.0
package
http: ^0.13.3
My code
import 'package:http/http.dart' as http;
final url = Uri.parse('https://www.google.com');
void getStatusCode() async {
http.Response response = await http.get(url);
if (response.statusCode == 200) {
print('exists');
} else {
print('not exists');
}
}
and call getStatusCode()
This is most likely a cross origin request problem otherwise known as CORS. You are running this on the web. If you were to run it on android or iOS you would be fine, but in web you can't just make a network request to another site without that other site allowing you to do so via following some protocols regarding CORS.
The problem happens because the domain that your webpage is running on which is most likely localhost is not googl.com so it's a different origin.
Also the 200 http code is for checking if a request is successful that is the right terminology it's important to keep that in mind.
The code looks good and also functional. If there is no internet it will throw exception Unhandled Exception: SocketException. else it will print exists.

What does "has been blocked by CORS policy" mean? [duplicate]

This question already has answers here:
No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API
(26 answers)
Closed 1 year ago.
This has been marked as a duplicate which is NOT true. This is a mobile app, NOT a web app. There is no originating domain, like the proposed answer has for a web app.
I am trying to use the salesforce api with flutter / dart. I get the following error:
Access to XMLHttpRequest at 'https://instancename.my.salesforce.com/services/data/' from origin 'http://localhost:53765' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
It does not matter if I try to get a session token
void getData() async{
var headers = {
'Authorization': 'Bearer access_token',
};
var res = await http.get('https://instancename.my.salesforce.com/services/data/v20.0/', headers: headers);
if (res.statusCode != 200) throw Exception('http.get error: statusCode= ${res.statusCode}');
print(res.body);
}
or just the version
void getData() async{
Response response=await get("https://instancename.my.salesforce.com/services/data/");
print(response.body);
}
everything fails.
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any other origins (domain, scheme, or port) than its own from which a browser should permit loading of resources. ... For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts.
you have to set cars policy to your web server not flutter application it happen when you want to connect to you web api on internet if you run your web api on local you'r not get that error