Kavana Shettigar
Kavana Shettigar

Reputation: 251

http request is blocked by Cors policy for flutter web

I have an Android, Ios and web app that's using php as a backend. All Api's are working fine in both android and ios but throwing CORS error in web. Getting error like this

Access to XMLHttpRequest at 'https://example.com/api' from origin 'http://localhost:49168' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I tried to send headers: {'Access-Control-Allow-Origin': 'http://localhost:49168', "Origin": "http://localhost:49168" }, to http request. Web is working smoothly if i add CORS extension for chrome. Please help me out

Upvotes: 7

Views: 16673

Answers (3)

Vignesh
Vignesh

Reputation: 160

You need to configure your app server like node/express js

const cors = require('cors');

app.use(cors({
   origin: ["https://yourapidomain.com"],
   methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
   credentials : true // allows cookies
}));

Upvotes: 0

Keegan Skeate
Keegan Skeate

Reputation: 31

I want to post my solution because my server's CORS is configured correctly (as far as I can tell) and the blocking appears to be a result of the Flutter framework. I think that I solved my problem by removing the Cookie from the request headers. From my understanding, this is the equivalent of withCredentials = false. I added the following code right before I made my request:

request.headers.remove('Cookie');

Hopefully this helps someone as I found resolving CORS issues to be the hardest part of publishing a Flutter app to the web. If anyone has any better insight into this issue, then I'm definitely happy to learn more.

If you need to know about my environment, then I am using Django, Django REST framework, and django-cors-headers:

INSTALLED_APPS = [
    ...,
    "corsheaders",
    ...,
]

MIDDLEWARE = [
    ...,
    # Place CorsMiddleWare above any middleware that may return a response.
    "corsheaders.middleware.CorsMiddleware",
    'django.middleware.security.SecurityMiddleware',
    ...,
]

# Allow CORS from the following domains.
# See: https://github.com/adamchainz/django-cors-headers/tree/main
CORS_ALLOWED_ORIGIN_REGEXES = [
    r"^https://\w+\.your-domain\.com$",
]

I have also configured the following for Flutter:

  1. I have added --disable-web-security to $FLUTTER_SDK/packages/flutter_tools/lib/src/web/chrome.dart
  2. I find it necessary to run flutter clean & flutter pub get before flutter build web --web-renderer html.
  3. I find that --web-renderer html is necessary.

Here is my code for making a POST request from my Flutter app:

import 'package:http/http.dart' as http;

// Define your request.
final client = http.Client();
final request;
final body = jsonEncode(data); // Here you can pass your data.
String idToken = await getUserToken(); // In my case I'm passing a user token.
String url = 'your-api.com';

// Define your headers.
final headers = {
  'Content-Type': 'application/json;charset=UTF-8',
  'Accept': 'application/json',
  'Authorization': 'Bearer $idToken',
}

// Create a POST request.
request = http.Request('POST', Uri.parse(url))
  ..headers.addAll(headers)
  ..body = body;

// Ensure the client doesn't add cookies.
request.headers.remove('Cookie');

// Get the response.
final response = await client.send(request).then(http.Response.fromStream);

Upvotes: 0

ישו אוהב אותך
ישו אוהב אותך

Reputation: 29783

The same problems hit me two weeks ago. For me, the following error is giving me a wrong direction to checking the problem:

Access to XMLHttpRequest at 'https://example.com/api' from origin 'http://localhost:49168' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

It says something about the request, but turns out it had nothing to do with the request. And it also had nothing to do with the web server (apache or nginx in my case).

The solution is by adding header to the response (yes, response) from your backend. I don't know the solution for php code, but I use the following code in my golang backend to add header to the response:

// Adding CORS header to response.
func (server *WebUploadServer) addCorsHeader(res http.ResponseWriter) {
    headers := res.Header()
    // use your domain or ip address instead of "*".
    // Using "*" is allowing access from every one
    // only for development.
    headers.Add("Access-Control-Allow-Origin", "*")
    headers.Add("Vary", "Origin")
    headers.Add("Vary", "Access-Control-Request-Method")
    headers.Add("Vary", "Access-Control-Request-Headers")
    headers.Add("Access-Control-Allow-Headers", "Content-Type, Origin, Accept, token")
    headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
}


// Here we handle the web request.
func (server *WebUploadServer) webHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Println("Endpoint hit")

    server.addCorsHeader(w) // Here, we add the header to the response

    switch r.Method {
    case "POST":
        // do something here.
    case "OPTIONS":
        w.WriteHeader(http.StatusOK)
    case "GET":
        fallthrough
    default:
        fmt.Fprintf(w, "Sorry, only  POST method is supported.")
    }
}

Upvotes: 6

Related Questions