patternjavascriptCritical
No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API
Viewed 0 times
dataapiaccessfromrequestedheaderthecontrolrestallow
Problem
I'm trying to fetch some data from the REST API of HP Alm. It works pretty well with a small curl script—I get my data.
Now doing that with JavaScript, fetch and ES6 (more or less) seems to be a bigger issue. I keep getting this error message:
Fetch API cannot load . Response to preflight request doesn't
pass access control check: No 'Access-Control-Allow-Origin' header is
present on the requested resource. Origin 'http://127.0.0.1:3000' is
therefore not allowed access. The response had HTTP status code 501.
If an opaque response serves your needs, set the request's mode to
'no-cors' to fetch the resource with CORS disabled.
I understand that this is because I am trying to fetch that data from within my localhost and the solution should be using Cross-Origin Resource Sharing (CORS). I thought I actually did that, but somehow it either ignores what I write in the header or the problem is something else.
So, is there an implementation issue? Am I doing it wrong? I can't check the server logs unfortunately. I'm really a bit stuck here.
I am using Chrome. I also tried using that Chrome CORS Plugin, but then I am getting another error message:
The value of the 'Access-Control-Allow-Origin' header in the response
must not be the wildcard '*' when the reque
Now doing that with JavaScript, fetch and ES6 (more or less) seems to be a bigger issue. I keep getting this error message:
Fetch API cannot load . Response to preflight request doesn't
pass access control check: No 'Access-Control-Allow-Origin' header is
present on the requested resource. Origin 'http://127.0.0.1:3000' is
therefore not allowed access. The response had HTTP status code 501.
If an opaque response serves your needs, set the request's mode to
'no-cors' to fetch the resource with CORS disabled.
I understand that this is because I am trying to fetch that data from within my localhost and the solution should be using Cross-Origin Resource Sharing (CORS). I thought I actually did that, but somehow it either ignores what I write in the header or the problem is something else.
So, is there an implementation issue? Am I doing it wrong? I can't check the server logs unfortunately. I'm really a bit stuck here.
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('GET', 'POST', 'OPTIONS');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}I am using Chrome. I also tried using that Chrome CORS Plugin, but then I am getting another error message:
The value of the 'Access-Control-Allow-Origin' header in the response
must not be the wildcard '*' when the reque
Solution
This answer covers a lot of ground, so it’s divided into three parts:
How to use a CORS proxy to avoid “No Access-Control-Allow-Origin header” problems
If you don’t control the server your frontend code is sending a request to, and the problem with the response from that server is just the lack of the necessary
You can easily run your own proxy with code from https://github.com/Rob--W/cors-anywhere/.
You can also easily deploy your own proxy to Heroku in just 2-3 minutes, with 5 commands:
After running those commands, you’ll end up with your own CORS Anywhere server running at, e.g.,
Now, prefix your request URL with the URL for your proxy:
Adding the proxy URL as a prefix causes the request to get made through your proxy, which:
The browser then allows the frontend code to access the response, because that response with the
This works even if the request is one that triggers browsers to do a CORS preflight
How to avoid the CORS preflight
The code in the question triggers a CORS preflight—since it sends an
https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
Even without that, the
What “preflight” means: before the browser tries the
It works pretty well with a small curl script - I get my data.
To properly test with
…with
The response the browser needs from that
If the
The server in the question responds to the
So you’ll never be able to make
The way to avoid triggering a preflight for the case in the question would be:
How to fix “Access-Control-Allow-Origin header must not be the wildcard” problems
I am getting another error message:
The value of the 'Access-Control-Allow-Origin' header in the response
must not be the wildcard '*' when the request's credentials mode is
'include'. Origin '
access. The credentials mode of reques
- How to use a CORS proxy to avoid “No Access-Control-Allow-Origin header” problems
- How to avoid the CORS preflight
- How to fix “Access-Control-Allow-Origin header must not be the wildcard” problems
How to use a CORS proxy to avoid “No Access-Control-Allow-Origin header” problems
If you don’t control the server your frontend code is sending a request to, and the problem with the response from that server is just the lack of the necessary
Access-Control-Allow-Origin header, you can still get things to work—by making the request through a CORS proxy.You can easily run your own proxy with code from https://github.com/Rob--W/cors-anywhere/.
You can also easily deploy your own proxy to Heroku in just 2-3 minutes, with 5 commands:
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku masterAfter running those commands, you’ll end up with your own CORS Anywhere server running at, e.g.,
https://cryptic-headland-94862.herokuapp.com/.Now, prefix your request URL with the URL for your proxy:
https://cryptic-headland-94862.herokuapp.com/https://example.comAdding the proxy URL as a prefix causes the request to get made through your proxy, which:
- Forwards the request to
https://example.com.
- Receives the response from
https://example.com.
- Adds the
Access-Control-Allow-Originheader to the response.
- Passes that response, with that added header, back to the requesting frontend code.
The browser then allows the frontend code to access the response, because that response with the
Access-Control-Allow-Origin response header is what the browser sees.This works even if the request is one that triggers browsers to do a CORS preflight
OPTIONS request, because in that case, the proxy also sends the Access-Control-Allow-Headers and Access-Control-Allow-Methods headers needed to make the preflight succeed.How to avoid the CORS preflight
The code in the question triggers a CORS preflight—since it sends an
Authorization header.https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Preflighted_requests
Even without that, the
Content-Type: application/json header will also trigger a preflight.What “preflight” means: before the browser tries the
POST in the code in the question, it first sends an OPTIONS request to the server, to determine if the server is opting-in to receiving a cross-origin POST that has Authorization and Content-Type: application/json headers.It works pretty well with a small curl script - I get my data.
To properly test with
curl, you must emulate the preflight OPTIONS the browser sends:curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"…with
https://the.sign_in.url replaced by whatever your actual sign_in URL is.The response the browser needs from that
OPTIONS request must have headers like this:Access-Control-Allow-Origin: http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization
If the
OPTIONS response doesn’t include those headers, the browser will stop right there and never attempt to send the POST request. Also, the HTTP status code for the response must be a 2xx—typically 200 or 204. If it’s any other status code, the browser will stop right there.The server in the question responds to the
OPTIONS request with a 501 status code, which apparently means it’s trying to indicate it doesn’t implement support for OPTIONS requests. Other servers typically respond with a 405 “Method not allowed” status code in this case.So you’ll never be able to make
POST requests directly to that server from your frontend JavaScript code if the server responds to that OPTIONS request with a 405 or 501 or anything other than a 200 or 204 or if doesn’t respond with those necessary response headers.The way to avoid triggering a preflight for the case in the question would be:
- if the server didn’t require an
Authorizationrequest header but instead, e.g., relied on authentication data embedded in the body of thePOSTrequest or as a query param
- if the server didn’t require the
POSTbody to have aContent-Type: application/jsonmedia type but instead accepted thePOSTbody asapplication/x-www-form-urlencodedwith a parameter namedjson(or whatever) whose value is the JSON data
How to fix “Access-Control-Allow-Origin header must not be the wildcard” problems
I am getting another error message:
The value of the 'Access-Control-Allow-Origin' header in the response
must not be the wildcard '*' when the request's credentials mode is
'include'. Origin '
http://127.0.0.1:3000' is therefore not allowedaccess. The credentials mode of reques
Code Snippets
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku masterhttps://cryptic-headland-94862.herokuapp.com/https://example.comcurl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');Context
Stack Overflow Q#43871637, score: 1830
Revisions (0)
No revisions yet.