http request is blocked by Cors policy for flutter web
Asked Answered
L

3

7

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

Lugansk answered 16/2, 2021 at 10:40 Comment(8)
possible duplicate of #60192183 ?Carthage
I am using form-data. Where should i add those requests?Lugansk
Your API needs to send the Access control allow origin "your domain" / "*" headers. I'd recommend reading up on CORS developer.mozilla.org/en-US/docs/Web/HTTP/CORSCarthage
I already sent in post request but throwing same errorLugansk
CORS is not something you control from the front end (Flutter). Your PHP API must send these headers. It is outlined in the link I sent.Carthage
sent like await http.post(url, headers: {"Access-Control-Allow-Origin": "*", },// Required for CORS support to work, body: { ....... });Lugansk
Does this answer your question? Cross-Origin Request Headers(CORS) with PHP headersCarthage
Let us continue this discussion in chat.Lugansk
P
6

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.")
    }
}
Participation answered 16/2, 2021 at 11:36 Comment(2)
You are right. Those headers belong to the response, not request. So it's the backend that has to handle that CORS. It reminds me of my answer in the link : #43872137Tbar
Great answer. I do have CORS enabled in my backend, i.e. the response has the header "Access-Control-Allow-Origin", "*". But it still gives me this error. Are you sure I need all the other headers as well?Yield
O
0

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);
Outlive answered 22/8, 2023 at 18:11 Comment(0)
R
0

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
}));
Resuscitator answered 9/8, 2024 at 11:16 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.