Getting CORS error only when heading request headers - javascript

Stuck with a very annoying error. When I am sending a request to my REST server from JavaScript:
const response = await fetch(url);
const res = await response.json();
Everything works fine. But when I am trying to add headers:
const headers = {
headers: {
'Content-Type': 'application/json',
'x-access-token': document.getElementById("token").value
}
};
const response = await fetch(url, headers);
const res = await response.json();
All of a sudden I am getting CORS errors.
My server executes at the beginning of each route:
def _auth_stub() -> None:
token = request.headers.get('x-access-token', None)
if token != 'SOME-HARDCODED-TOKEN':
abort(401)
And at the end:
def _make_response(data: JsonData) -> Response:
response = flask.jsonify(data)
response.headers.add('Access-Control-Allow-Origin', 'https://1.2.3.4')
response.headers.add('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
response.headers.add('Access-Control-Allow-Headers: Origin, Content-Type, x-access-token');
return response
Note: My HTML and JS are on the same server. The CORS error only happens when I add the headers!
The CORS error:
Access to fetch at 'https://1.2.3.4:5005/activities' from origin
'https://1.2.3.4' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
One change I noticed is that with the headers, a preflight is sent. But no apparant reason why the preflight fails...

Related

Deezer API fail request

i'm trying to consume deezer api, but idk how to do it.
I already read the documentation, learn how I can get my token, but when I'm trying to request i got this error:
Access to fetch at 'https://api.deezer.com/album/302127' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
how can I solve this?
url: https://api.deezer.com/album/302127
idk the problem with my request.
async function getAlbum() {
try {
const response = await fetch("https://api.deezer.com/album/302127", {
headers: {
"Authorization": "Bearer " + access_token
}
});
const data = await response.json();
console.log(data);
} catch (error) {
console.log(error);
}
}
getAlbum();

How to use Fetch API for GET request

I want to GET JSON from the endpoint https://api.brawlstars.com/v1/brawlers.
(https://api.brawlstars.com/v1/brawlers?Authorization="Bearer%20[My API Key]")
Here's my Code:
let url = 'https://api.brawlstars.com/v1/brawlers'
fetch(url, {
method: "GET",
headers: {
"Authorization": "Bearer **USER'S API KEY GOES HERE**"
}
}).then((response) => {
let json = response.json();
console.log(json);
}).catch((err) => {
console.error(err)
});
This is the output (error):
Access to fetch at 'https://api.brawlstars.com/v1/brawlers' from origin 'http://127.0.0.1:8887' has been
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If
an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS
disabled.
sketch.js:3 GET https://api.brawlstars.com/v1/brawlers net::ERR_FAILED
127.0.0.1/:1 Uncaught (in promise) TypeError: Failed to fetch
What am I missing?
In your header, you need to enable CORS like CBroe said :
headers.append('Access-Control-Allow-Origin', 'http://127.0.0.1:8887');
headers.append('Access-Control-Allow-Credentials', 'true');
Edit :
The server (that the POST request is sent to) needs to include the Access-Control-Allow-Headers header (etc) in its response. Putting them in your request from the client has no effect.
This is because it is up to the server to specify that it accepts cross-origin requests (and that it permits the Content-Type request header, and so on) – the client cannot decide for itself that a given server should allow CORS.

Problems with CORS and JSON

I habe a client written in Javascript (react) which runs on localhost:3000
Here I have a button that sends the credentials to my backend written in python and using flask. The endpoint is running on localhost:5000/login.
My frontend code looks like this:
loginToDatabase = async () => {
console.log("login to database. user: " + this.state.user+" pw: "+this.state.password);
const response = await fetch("http://localhost:5000/login",{
method: 'POST',
body: {
"user": this.state.user,
"password": this.state.password
},
headers: {
"Content-Type": "application/json"
}
});
console.log("response: "+response)
};
My backend code looks like this:
#app.route("/login", methods=['POST'])
def login():
jsonRequest = request.get_json()
receivedUser = jsonRequest.get('user')
receivedPassword = jsonRequest.get('password')
isConnected = opendatabase.openDatabase('localhost',receivedUser,receivedPassword)
if(isConnected == True):
body = json.dumps({
"connection":isConnected,
})
jsonResponse = Response(
body,
mimetype="application/json",
headers={
"Access-Control-Allow-Origin" : "*",
}
)
return (jsonResponse)
else:
body = isConnected
jsonResponse = Response(
body,
headers={
"Access-Control-Allow-Origin" : "*",
)
return (jsonResponse, 401)
Testing the API with Postman works as expected. However using the frontend I receive this error:
Access to fetch at 'http://localhost:5000/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
After doing some research I figured out why this happens and that I need the header
"Access-Control-Allow-Origin" : "*"
which I included. But still could not make it work.
I then read here https://developer.mozilla.org/de/docs/Web/HTTP/CORS that does not work with application/json.
The only allowed values for the Content-Type header are:
application/x-www-form-urlencoded,
multipart/form-data,
text/plain
However I also read here Can't send a post request when the 'Content-Type' is set to 'application/json' that I can set a header
->header('Access-Control-Allow-Headers', 'Content-Type');
which I also tried like this:
if(isConnected == True):
body = json.dumps({
"connection":isConnected,
})
jsonResponse = Response(
body,
mimetype="application/json",
headers={
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Headers": "Content-Type",
}
)
return (jsonResponse)
else:
body = isConnected
jsonResponse = Response(
body,
headers={
"Access-Control-Allow-Origin" : "*",
"Access-Control-Allow-Headers": "Content-Type"
}
)
return (jsonResponse, 401)
But that does also not work.
There are also many more posts about this topic but so far I could not find a solution. I am also new to APIs and webdevelopment.
And also I think my shown login process is far from perfect. It is really just about getting the REST call to work.
Is there a way to solve this and still using JSON? Surely I could use someting like text/plain but that would not be satisfying.
Also (maybe related) if I use text/plain in the frontend I don't receive the error, but in the backend I don't know how the receive the data send via POST. As you can see in the attached picture, I seem to get an empty object?
Where is my mistake and what is the best way to solve this issue with JSON?

CORS error using fetch API - React create app

I'm consuming an API using fetch but i'm getting CORS error.
I tried multiples headers, but I'm not understading what's the problem.
I'm not the owner of the API, so I couldn't change it, but checking the response it's returning access-control-allow-origin.
Following is my request method:
export const execPOST = (url, body) => {
return fetch(url, {
method: "POST",
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json"
},
body: JSON.stringify(body)
});
};
The response is:
Request URL: http://api
Request Method: OPTIONS
Status Code: 405 Method Not Allowed
Remote Address: ip
Referrer Policy: no-referrer-when-downgrade
Response Headers:
Access-Control-Allow-Origin: *
Isn't this response above enough to allow my request?
console error:
OPTIONS http://api net::ERR_ABORTED 405 (Method Not Allowed)
Access to fetch at 'http://api' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
I got this working (meanwhile I develop) using "https://cors-anywhere.herokuapp.com/", but I don't think that I should use this for production enviroment.
I found a lot of material about this problem, but nothing that worked besides implements a backend to make the request or use something else as a proxy to make the request and so on...
Update code as given below (use 'mode' with the value 'no-cors' ):
For more details follow the link => https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
export const execPOST = (url: string, body: any) => {
return fetch(url, {
mode: 'no-cors',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
};
CORS headers are set by the API to protect users from malicious code making requests to sites on their behalf.
This means that you cannot enable or disable it from the client side as the Access-Control-Allow-Origin header is a server side only header.
If you don't have access to the API to change the headers then you won't be able to use the API from the client side.
In production you would have to create your own API that will handle the requests to the API you are trying to contact.

Fix 'cors' request between different localhosts. 405 (Method Not Allowed)

I use the following code to request the file:
function getData(imageEndpoint) {
return fetch(imageEndpoint, {
mode: 'cors'
})
.then(response => {
console.log(response);
})
.then(data => {
if (!('caches' in window)) {
return caches.open(cacheName)
.then(cache => {
return cache.put(imageEndpoint, data);
});
}
return data;
})
.catch(e => {
console.log('Request issue, ', e);
});
}
Which outputs in following error message:
Failed to load http://localhost:7000/image.jpg: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
P.S The server works on :8000
When I add cors header
return fetch(imageEndpoint, {
mode: 'cors',
headers: {
'Access-Control-Allow-Origin': '*'
}
})
The following error is beeing thrown:
http://localhost:7000/image.jpg 405 (Method Not Allowed)
index.html:1 Failed to load http://localhost:7000/image.jpg: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 405. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Can you please suggest how the request should be setup in order succesfully receive the file?
you need to have the header Access-Control-Allow-Origin: URL Here or Access-Control-Allow-Origin: * on both the OPTIONS response and the POST response. You should include the header Access-Control-Allow-Credentials: true on the POST response as well.
Your OPTIONS response should also include the header Access-Control-Allow-Headers: origin, content-type, accept to match the requested header.

Categories