5

I am using flutter-web with .net webapi. To shoot my requests, I have tried Dio and Dart HTTP packages. Neither of the two have worked because of CORS issue. Kindly tell me what am I doing wrong. is there a way to get around this problem ? There is no problem with api when it comes to shoot them from postman .

Sample code

I have added var cors = new EnableCorsAttribute("", "", "*"); config.EnableCors(); in webapi as well.

Flutter HTTP Requests first of the two is built on dio.

Dio dio= new Dio(); Future postData2(user) async{ debugPrint(user.toString()); dynamic data = { 'phone_number': user['country_code'] + user['phone_number'], 'password':user['password'] }; final String pathUrl = "http://localhost:62435/api/Token/GetToken"; var response = await dio.post(pathUrl, data:data, options: Options( headers: { 'content-type': 'application/json', 'Access-Control-Allow-Origin':'true' }, )); return response.data; } 

//Http : dart

 Future postData(user) async{ dynamic data = { 'phone_number': user['country_code'] + user['phone_number'], 'password':user['password'] }; final String pathUrl = "http://localhost:62435/api/Token/GetToken"; dynamic response = _http.post( pathUrl, body : data, headers : { HttpHeaders.contentTypeHeader : 'application/json', //'Access-Control-Allow-Origin':'true' } ); debugPrint( //response.statusCode + " " + response.data.toString()); } 

For dio, at least the checkup request is sent enter image description here

enter image description here

enter image description here

with Dio I get following errors.

Dio Request headers in network tab. The request remains pending. and does not finish.

Request URL: http://localhost:62435/api/Token/GetToken Referrer Policy: no-referrer-when-downgrade Provisional headers are shown Access-Control-Allow-Origin: true content-type: application/json; charset=utf-8 Referer: http://localhost:63440/ User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 {phone_number: "123124", password: "safaSF"} 
5
  • Access to XMLHttpRequest at 'http://localhost:62435/api/Token/GetToken' from origin 'http://localhost:59789' This line in the error log tells you that you are doing cross domain request. Hence its not getting through you should add the http://localhost:59789 in the server side as one of allowed origins. However in usual cases for testing in postman this will work because its not from another web domain. For testing purpose in the server side you can allow all domains using a * in the server side. If you provide the which server you are using we can find how to configure for the server. Commented Nov 22, 2020 at 16:45
  • Hi Abhilash, ive tried var cors = new EnableCorsAttribute("", "", "*"); config.EnableCors(); in webapi. Commented Nov 22, 2020 at 17:48
  • this is my new request Future postData(user) async{ dynamic data = {'phone_number': user['country_code'] + user['phone_number'],'password':user['password']}; final String pathUrl = "localhost:62435/api/Token/GetToken"; print(jsonEncode(data)); dynamic response = _http.post(pathUrl,body : jsonEncode(data),headers : {HttpHeaders.contentTypeHeader : 'application/json','Access-Control-Allow-Origin':'true'}); if (response.statusCode == 200) { return response; } else { throw Exception('Failed to load '); } } Commented Nov 22, 2020 at 17:52
  • Now you have removed the old error. Does this mean its a new error? Did you try my suggested answer.? Commented Nov 23, 2020 at 11:24
  • This one was a new error at the time. Your suggestions were right. after a while this issue was solved. I will post solution soon. Commented Nov 23, 2020 at 12:34

3 Answers 3

2

When you are using Flutter Web and call an API, Flutter uses:
Preflight request (before call the API)

It is a request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers.
It is an OPTIONS request, using three HTTP request headers:

1.Access-Control-Request-Method, 2.Access-Control-Request-Headers, 3.and the Origin header. 

In that case you need to check if your API is allowed for methods OPTIONS.

Access-Control-Allow-Origin: https://foo.bar.org
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE

If your API not accept, you need to configurare your response to send OPTIONS in
Access-Control-Allow-Methods for example:

Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE
Access-Control-Request-Headers: origin, x-requested-with
Origin: https://foo.bar.org

More details in Mozilla Glossary

Sign up to request clarification or add additional context in comments.

Comments

0

The browser debugger (F12), and Wireshark between the flutter client and the server, are very valuable in figuring out this issue.

The browser debugger quickly shows it erroring on a preflight check. There isn't anything to do here on the flutter web side. The support needs to be provided by the server.

In my case, my server is written in Go, and using Gorrila-Mux. I followed this nice article but still had an issue. I still saw in Wireshark the OPTIONS request getting denied by the server, and nothing in the server logs explaining why.

This issue helped me find the solution. There were a lot of incorrect answers along the way, and ultimately this is what I've learned:

  1. The server must react to OPTION requests, where the client is usually sending Access-Control-Request-Method and Access-Control-Request-Headers (depends on exactly what request is being made).
  2. Access control response headers from the server are required. In my case, Access-Control-Allow-Headers and Access-Control-Allow-Origin are the non-optional ones.
  3. Some answers have said Access-Control-Allow-Origin: * is not allowed -- it is, as the RFC explains.
  4. If Access-Control-Allowed-Methods is sent in the response, it does NOT require OPTIONS to be listed.

Since I am using Gorilla mux, I also found the OPTIONS route does not need to be explicitly registered as a handler; the middleware will process it.

And minimally, for my apis there's just one response header that must be configured in Gorilla mux: Allowed Headers. The middleware will respond with Access-Control-Allow-Headers as specified, and, Access-Control-Allow-Origin: *. Per comments in cors.go:

// Content-Type must be explicitly declared if accepting Content-Types other than // application/x-www-form-urlencoded, multipart/form-data, or text/plain. 

The response Access-Control-Allow-Headers automatically filters out header keys that the client didn't request.

So then my server code uses

import "github.com/gorilla/handlers" 

and has

 cors := []handlers.CORSOption{} cors = append(cors, handlers.AllowedMethods([]string{"GET", "POST"})) cors = append(cors, handlers.MaxAge(3600)) cors = append(cors, handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"})) olist := []string{} whitelist := os.Getenv("CORS_ALLOWED_ORIGINS") if whitelist != "" { parts := strings.Split(whitelist, ",") olist = append(olist, parts...) } if len(olist) == 0 { olist = append(olist, "*") } cors = append(cors, handlers.AllowedOrigins(olist)) 

with

http.ListenAndServe(iface, handlers.CORS(cors...)(myRouter)) 

Comments

-2

From the comments above I assume you are using ASP .net web api. If this is the case, then you should perhaps use the constructor for EnableCorsAttribute properly. As per the documentations here, you have to use the first parameter in the constructor to pass allowed list of origins. In your case you can do either of the following.

Allow all origins

public EnableCorsAttribute( "*", "*", "" ) 

Allow specific origins

public EnableCorsAttribute( "http://localhost:59789,http//localhost:another_port,http://example_domain.com", "*", "" ) 

Also note that Access-Control-Allow-Origin is response header. You should not set it in your request headers. Its tells the browser or the client from which origins are allowed to access the server. Read more about CORS here.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.