Reputation: 251
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
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
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:
--disable-web-security
to $FLUTTER_SDK/packages/flutter_tools/lib/src/web/chrome.dart
flutter clean & flutter pub get
before flutter build web --web-renderer html
.--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