'Flutter web app does not work with local golang http server

I know it sounds like a beginner's question, but here I go: I've developed a small app to be used locally in restaurants for the waiters to be able to take orders on their phones. Pretty basic. I also developed a simple go HTTP server to implement the necessary API. It works fine on the "mobile" version, both in the emulator and actual devices.

The next step is to port the app so it can be used by the customers in their phones' browsers. When I changed it to the web version, it worked correctly in Chrome and Edge, at least in terms of UI and navigation. But I am not able to use the API because I get the XMLHTTPError in all requests (that's what the error capture returns, I don't know how to get more details on that). I did a little research on the matter, and one of the answers includes changing configurations in Chrome, etc., which would be impossible for the customers to do. Also, it seems that a possibility is changing the go server from HTTP to HTTPS.

This is my go lang HTTP server code (part of)

func main() {
r := mux.NewRouter()
http.Handle("/", r)
r.HandleFunc("/api/getgarcon", get_garcon).Methods("GET")
log.Fatal(http.ListenAndServe(":8000", r))
}

get_garcon is a function that returns a JSON list of the registered waiters for login. As I said before, it works correctly if the client is a mobile app.

This is the flutter/dart code in the app

Future<List<Garcon>> getGarcon() async {
  var data;
  try {
    print(glbHttpServer + "api/getgarcon");
    data = await http.get(
      glbHttpServer + "api/getgarcon",
      headers: {'Content-Type': 'application/json','Access-Control-Allow-Origin':'*',
      'Access-Control-Allow-Methods':'HEAD, GET, POST, PUT, PATCH, DELETE, OPTIONS',
      'Access-Control-Allow-Headers':'X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method,Access-Control-Request-Headers, Authorization'},
    );
  } catch (e) {
    print("getgarcon=" + e.toString());
  }
  etc...

glbHttpServer is a variable whose value is like "http://192.168.29.94:8000/" I added those headers trying to get this to work for the web app. Previously (for the mobile app) there was only the 'Content-Type': 'application/json' header.

As additional information, both the web app and the go server are on the same machine. If I type http://192.168.29.94:8000/api/getgarcon in a Chrome window (or Edge window), it works. Same with localhost or 127.0.0.1.

So what I'm asking here is: which is the least complicated way to go? Adding some different code in my app? Changing the server from HTTP to HTTPS? Or is another solution available that I haven't found?

And most important: is it worth the effort, given the current state of the flutter web?

Thanks for any help.



Solution 1:[1]

You need to add those CORS headers to the response on the server, not the request from Flutter. In Go, it would look like this. You can create a middleware to handle this for all your endpoints.

func main() {
  http.HandleFunc("/", func (w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Access-Control-Allow-Origin", ...)
    w.Header().Set("Access-Control-Allow-Methods", ...)
    w.Header().Set("Access-Control-Allow-Headers", ...)

    ...
  })
  
  ...
}

Mobile apps do not have the same CORS restrictions, which is why you would not have noticed it. However, if you tried to load your Flutter website in a mobile browser, you would notice the same behavior.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dillon Nys