REST API request Flutter web CORS issue - api

I hope you are well
I have a problem with flutter web. I try to make an API REST request to https://timeapi.io/api/TimeZone/zone?timeZone=Europe/Amsterdam to get the time from a specific location but I get this error XMLHttpRequest error and when displaying the console in the browser, I get this error (image below)
After a few days of research, I know that it is CORS and I was able to test a few solutions but without success.
Here is what I could do:
Future<void> _getCurrentDateTime() async {
try {
var url = Uri.https('timeapi.io', 'TimeZone/zone', {'timeZone': 'Europe/Amsterdam'});
final headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST, GET, OPTIONS, DELETE",
"Origin": "https://localhost"
};
var response = await http.get(url, headers: headers);
log('Response status: ${response.statusCode}');
log('Response body: ${response.body}');
// return now;
} catch (e) {
rethrow;
}
}
How to solve this error? Thanks

You are missing /api/ as part of the url in line:
var url = Uri.https('timeapi.io', 'TimeZone/zone', {'timeZone': 'Europe/Amsterdam'});
If you notice the error on your console you will see that the URL that is printed is also missing the api in the URL.
Which in turn ends up in a 404, if you open https://timeapi.io/TimeZone/zone?timeZone=Europe/Amsterdam in the browser you'll find a 404 response.
Thus, the 404 doesn't contain CORS headers in the response, resulting in the CORS error you see on the browser console.
If you want to call https://timeapi.io/api/TimeZone/zone?timeZone=Europe/Amsterdam
The code should probably be
var url = Uri.https('timeapi.io', 'api/TimeZone/zone', {'timeZone': 'Europe/Amsterdam'});
Also, you may want to remove these headers as they're supposed to be sent from the backend and not the frontend. The following lines of code are redundant.
final headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST, GET, OPTIONS, DELETE",
"Origin": "https://localhost"
};

Related

CORS header ‘Access-Control-Allow-Origin’ missing on response in addon but not on request

I am creating a Firefox extension which posts some data to a database.
I made all parts in a modular fashion and am now combining everything piece by piece.
As such I know that my code to POST data to the database works.
Now here is the part that stumps me :
When I then add this code to my firefox extension
I get the following error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:3003/timed_shot_create. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 400.
Now ofcourse CORS was nothing new and to be expected when dealing with Cross Origin Resource Sharing, it is even in the name.
But the reason why I am here is because this pertains only to the response of the POST request. The request itself is fine and allowed with the following piece of config in the server:
app.use(
cors({
//todo change to proper origin when live
origin: "moz-extension://d07f1e99-96a0-4934-8ff4-1ce222c06d0d",
method: ["GET", "POST"],
})
);
Which was later changed to:
app.use(
cors({
origin: "*",
method: ["GET", "POST"],
})
);
And then simplified even more to:
app.use(cors())
This is in Nodejs btw using cors middleware.
But none of this seems to work when it is used inside a firefox extension, as a local client page works as intended but as soon as I add this to a firefox extension I get a CORS error specifically pertaining to the reponse message.
The client side post (in the background script of the extension) is:
async function postTimedShot(post_options) {
const response = await fetch(post_endpoint, post_options);
//console.log(response);
const json_response = await response.json();
console.log(json_response);
}
let post_options = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(response_data),
};
postTimedShot(post_options);
And the api looks like this:
app.post("/timed_shot_create", (req, res) => {
console.log("Received POST request");
const data = req.body;
console.log(data);
const timeStamp = data.time_stamp;
//TODO add screenshot and Description text maybe??
//const lastName = data.last_name
const queryString =
"INSERT INTO " + timed_shots_database + " (time_stamp) VALUES (?)";
getConnection().query(queryString, [timeStamp], (err, results, fields) => {
if (err) {
console.log("Failed to insert new user: " + err);
res.sendStatus(500);
return;
}
//Todo change this message when adding more data in body
//res.header("Access-Control-Allow-Origin", "moz-extension://d07f1e99-96a0-4934-8ff4-1ce222c06d0d");
res.json({
status: "Success!!!",
time_stamp: timeStamp,
});
console.log("Inserted a new user with id: ", results.insertId);
});
});
Furthermore, this extension is only for personal use and will work with a local server under my complete control so complications due to security or cloud usage that people want to mention are appreciated but not necessary (I think, I am a bit of novice).
I will be happy to clarify anything that is unclear, or change this post if necessary, but I think it is a unique question as far as I could see on SO. Additionally if I need to provide more of the codebase I will.
I will also update this post if I find out more about this problem.
Thank you for reading :3.
After reading about this post https://stackoverflow.com/a/53025865/5055963
on SO I found out that it had to do with the permissions in the manifest of the extension.
Adding this line: "://.localhost/*".
Solved the issue for me.

CORS 400 Bad Request with fetch, express server

I'm trying to send a POST request from 127.0.0.1:8080 to my express server in localhost:3000/trips
I'm having a lot of problem with the cors configuration
First, this is my method to do the POST request
async modifyTrip() {
let json = {
data: "test",
mezzo: "test",
coordinate: ["test"],
tappe: ["test"],
};
let modifyform = document.getElementById("add-form");
modifyform.onsubmit = async (e) => {
e.preventDefault();
await fetch("http://localhost:3000/trips", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: json,
});
};
}
On the server side if I put cors options at that point returns me that error:
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(
cors({
"Access-Control-Allow-Origin": "*",
"Allow-Methods": "GET, POST, DELETE, FETCH",
})
);
app.use("/user", userRoutes);
app.use("/trips", tripsRoutes);
If I try to change the position the error is different my it always gives me problem
app.use(
cors({
"Access-Control-Allow-Origin": "*",
"Allow-Methods": "GET, POST, DELETE, FETCH",
})
);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use("/user", userRoutes);
app.use("/trips", tripsRoutes);
I don't think the matter is of where I put it, but I can't fix this problem anyway. Maybe I have to change some headers in my client side, but i really can't figure it out
Thank you.
It's a 400 Bad Request error, so look up what that means:
The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (for example, malformed request syntax, invalid request message framing, or deceptive request routing).
So something is wrong with the request and the server is complaining (before it gets to the bit of code which would add the CORS response headers). The CORS error is a side-effect, not the main problem.
If you look at the Network tab of your browser's developer tools, you will be able to examine the request.
The body will look something like this:
[object Object]
Now, you said (using a Content-Type header) you were POSTing JSON, but [object Object] is not JSON (or even a usable representation of your data).
You need to pass JSON to body and not an object. Since you are passing an object, it gets stringified using the default JS mechanism (which gives "[object Object]").
Use JSON.stringify(your_object) to convert it to JSON.

get CORS problem when ty to get a token in keycloak with vuejs and axios

I trying to access one keycloak with axios in my vuejs app, but I receive the cors error, can someone help me please? (If I make a post from POSTMAN to my keycloak works fine)
I using this code:
const params = new URLSearchParams();
params.append("grant_type", "password");
params.append("client_id", "notas-front");
params.append("username", usuario.value);
params.append("password", password.value);
console.log(params);
const config = {
// withCredentials: true,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
};
axios.defaults.headers.common["Access-Control-Allow-Origin"] =
"http://localhost:8080";
axios
.post(
"http://localhost:8082/auth/realms/lumera/protocol/openid-connect/token",
params,
config
)
.then((response) => {
console.log(response);
});
and get this error:
but when I look the request I can't find the error:
the OPTIONS returns 200
but the POST dont
Postman doesn't care about Same Origin Policy, browser do. That's why your request is working in Postman but not in the browser.
Access-Control-Allow-Origin is a response header, you can't set it on the client request. And as you can see from the OPTIONS response headers your server is returning: Access-Control-Allow-Origin: http://localhost:8080
In a development environment the best way to solve this is setting a proxy in your vue configuration. Otherwise you should configure the server to allow requests from localhost:8080
Configure Web Origins properly in the Keycloak notas-front client config.

POST command to WebCeo API

Trying to connect to this WebCEO API.
function getProjects() {
var payload = {
"key": "CUSTOMER_KEY",
"method": "get_projects"
};
payload = JSON.stringify(payload);
var url = "https://online.webceo.com/api/";
var options = {
"method": 'POST',
"contentType" : "application/json",
"payload": payload
};
var response = UrlFetchApp.fetch(url, options);
}
Receiving "Request failed for https://online.webceo.com/api/ returned code 404".
Any hint on what else I need to include / change?
Body must contain the following:
json={"key": "YOUR_API_KEY", "method": "get_projects"}
Well, https://online.webceo.com/api/ does return a 404 when you just try to access it. Did you manage to get that page to not return a 404 error from another client?
Doing so will probably tell you what you're missing here.
However, I'd suspect their API might be having issues.
That's true, you don't make a GET request. You have to send parameters in the body of a POST request. Below is an example in CURL for a situation when you need to get the list of projects:
curl -X POST -d 'json={"key": "YOUR_API_KEY", "method": "get_projects" }' https://online.webceo.com/api/

mootools Request class and CORS

I'm trying to use CORS to have a script do an Ajax request to geonames.
My script calls this web service method: http://www.geonames.org/export/web-services.html#findNearby
If you check the response headers of the sample call, they include:
Access-Control-Allow-Origin: *
When I try this with mootools (version 1.4.5 just downloaded):
var urlGeonames = "http://api.geonames.org/findNearbyPlaceName";
var req = new Request({
method: 'get',
url: urlGeonames,
data: {
'lat': '89.18',
'lng': '-0.37',
'username': 'myusername',
'radius': '5'
}
}).send();
then I get an error that says :
XMLHttpRequest cannot load
http://api.geonames.org/findNearbyPlaceName?lat=89.18&lng=-0.37&username=myusername&radius=5.
Origin http://127.0.0.1 is not allowed by Access-Control-Allow-Origin.</pre>
On the other hand, when I try old style Ajax code like this:
invocation = new XMLHttpRequest();
if(invocation)
{
invocation.open('GET', urlFlickr, true);
invocation.onreadystatechange = handler;
invocation.send();
}
then it works and I get the XML response in the XHR responseXML.
I found this post A CORS POST request works from plain javascript, but why not with jQuery? that is similar. But here I'm not dealing with my server so I can only work on the javascript side.
Has anyone worked with CORS and mootools and can help on this issue ?
Thanks so much
JM
Hey man check out mootools more JSONP this will solve your problem:
http://mootools.net/docs/more/Request/Request.JSONP
Also it looks like your forgetting to ask for it in JSON format from geonames.org
Try something like:
var myJSONP = new Request.JSONP({
url: 'http://api.geonames.org/findNearbyPlaceNameJSON',
data: {
'lat': '89.18',
'lng': '-0.37',
'username': 'myusername'
},
onRequest: function(url){
// a script tag is created with a src attribute equal to url
},
onComplete: function(data){
// the request was completed.
console.log(data);
}
}).send();
Hope this helps!
The first answer on this other thread:
MooTools CORS request vs native Javascript
Might help.
Basically, the X-Requested-With header is automatically sent by the Mootools with the request, but the server either has to be configured to accept that header or you can remove it using
delete foo.headers['X-Requested-With'];
Before calling
foo.send();
To allow it by the server, you can add this to the .htaccess file of your script that gives back the JSON data:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
So yours would look like:
var myJSON = new Request({
url: 'http://api.geonames.org/findNearbyPlaceNameJSON',
data: {
'lat': '89.18',
'lng': '-0.37',
'username': 'myusername'
},
onRequest: function(url){
// a script tag is created with a src attribute equal to url
},
onComplete: function(data){
// the request was completed.
console.log(data);
}
});
delete myJSON.headers['X-Requested-With'];
myJSON.send();