'XMLHttpRequest error in flutter web [Enabling CORS AWS API gateway]
Note: It turns out that this had nothing to do with flutter and everything to do with the fact that I had set the API gateway to a Lambda Proxy
I am trying to hit an API endpoint from a Flutter web application, every time it errors out and gives me the following error.
Error getting sensor data: DioError [DioErrorType.RESPONSE]: XMLHttpRequest error.
I know there are several questions here on SO(like this and this) discussing this issue and the solution seems to be to enable CORS support on the server-side. I am using the AWS API gateway to build the API, I followed these instructions to enable CORS support from my API. Here are my CORS setting from the API gateway console.
The text in the "Access-Control-Allow-headers" is
'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
Enabling CORS on the API gateway didn't seem to help, I am still getting the same error on my flutter web app when I try to hit an API.
The funny thing is, the API work perfectly fine if I hit the API from chrome (i.e. pasting the API URL on the browser and hitting enter). It only fails when I try to hit the API from the flutter web app.
Question: How do I enable CORS support in my API gateway so my flutter web app can use the API ?
Solution 1:[1]
this worked for me, I added the below header on the lambda function
return {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*", // Required for CORS support to work
"Access-Control-Allow-Credentials": true, // Required for cookies, authorization headers with HTTPS
"Access-Control-Allow-Headers": "Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,locale",
"Access-Control-Allow-Methods": "POST, OPTIONS"
},
body: JSON.stringify(item)
};
Solution 2:[2]
My server was using nginx so I solved the problem by adding the following two lines to the server block of the sites-enabled config file for my API server:
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, HEAD";
My app only uses GET
and HEAD
so you may need to add other methods depending on your situation.
See also: How to Enable CORS in Apache and Nginx?
Solution 3:[3]
I was using Nodejs for my backend. When I sent a post request from Dio there was this error :"XMLHttpRequest error.".
Reason Behind this error: Suppose your flutter is running at localhost:5500 and nodejs server on localhost:3000. So, your browser fails to handle the request as they are running on different ports. That's we use CORS or Proxies to solve these problems.
Remember, this is a problem mainly associated with your browser. If you will use postman and send the same request, you will find everything working.
To solve this: I installed a NPM Package called CORS.
npm i cors
Then, start using it....
const cors = require("cors");
app.use(cors());
By just doing that your error will get resolved. And you don't need to add anything more.
Solution 4:[4]
Enable CORS in cpanel to enable CORS in your hosting account. you can enable it adding the following lines in the .htaccess file in your hosting account.
<IfModule mod_headers. ...
Header set Access-Control-Allow-Origin "*"
</IfModule>
? ?
Solution 5:[5]
This is a problem with both your backend and frontend especially if you need to add an authentication header. You need to do two things. Allow cors inyour backend and specify that your sending json in your frontend.
Frontend
var request = await http.post(
Uri.parse(url),
headers: {
"auth-token": idToken, // whatever headers you need
"content-type": "application/json" // This preventes empty response body
},
body: jsonEncode(<String, String>{
'name': name,
'email': email,
})
Backend
const cors = require('cors');
app.use(cors({
origin: '*',
allowedHeaders: 'X-Requested-With, Content-Type, auth-token',
}));
app.use("/api/user", authRoute); // this is the endpoint yoou're calling with your Flutter Web frontend
Solution 6:[6]
If you dont have access to the server side, it is a good idea set up a reverse proxy. I used a nginx proxy with minimum configuration, running in a docker container.
docker-compose.yml:
version : '3'
services :
nginx:
image: nginx:latest
container_name: nginx_container
ports:
- 3000:3000
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
nginx.conf:
events {
}
http {
server {
listen 3000;
location / {
proxy_pass http://original_address_and_port/;
}
}
}
Then, you can develop using http://localhost:3000 as API base, and nginx will send requests do original address and port.
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 | Abdulmalek Dery |
Solution 2 | Suragch |
Solution 3 | GAURAV JOSHI |
Solution 4 | |
Solution 5 | murage kibicho |
Solution 6 | Carlos Gonçalves |