Reputation: 3819
I am using HTML5 fetch API.
var request = new Request('https://davidwalsh.name/demo/arsenal.json');
fetch(request).then(function(response) {
// Convert to JSON
return response.json();
}).then(function(j) {
// Yay, `j` is a JavaScript object
console.log(JSON.stringify(j));
}).catch(function(error) {
console.log('Request failed', error)
});
I am able to use normal json but unable to fetch the data of above api url. It throws error:
Fetch API cannot load https://davidwalsh.name/demo/arsenal.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' 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.
Upvotes: 151
Views: 531488
Reputation: 1
The "No 'Access-Control-Allow-Origin' header" error happens when a server doesn’t allow cross-origin requests. To fix this, the server needs to enable CORS. On the client side, you can use mode: 'cors'
with the Fetch API or work around it using CORS proxies or custom server configurations. Just be careful not to compromise security, especially in production.
Upvotes: 0
Reputation: 113
The website that you are trying to fetch does not have the appropriate CORS header, namely the Access-Control-Allow-Origin
.
This header can only be controlled from the server side, and if the server is not yours, you cannot add it.
It is still possible to fetch the data if you relay your request through your backend. This will work since CORS only exists on the client side (browser). What you can do is to set up an endpoint with the purpose of fetching the target URL. Then you can adjust your frontend to fetch your endpoint instead of directly fetching the target URL.
If your website does not have a backend, you can use a CORS proxy. There is a self-hosted option like cors-anywhere or a hosted option like Corsfix.
With CORS proxy, typically you will add the proxy URL before the URL you are trying to fetch.
fetch("https://proxy.corsfix.com/?https://davidwalsh.name/demo/arsenal.json");
(I am affiliated with Corsfix)
Upvotes: 1
Reputation: 2991
Like epascarello said, the server that hosts the resource needs to have CORS enabled. What you can do on the client side (and probably what you are thinking of) is set the mode of fetch to CORS (although this is the default setting I believe):
fetch(request, {mode: 'cors'});
However this still requires the server to enable CORS as well, and allow your domain to request the resource.
Check out the CORS documentation, and this awesome Udacity video explaining the Same Origin Policy.
You can also use no-cors mode on the client side, but this will just give you an opaque response (you can't read the body, but the response can still be cached by a service worker or consumed by some API's, like <img>
):
fetch(request, {mode: 'no-cors'})
.then(function(response) {
console.log(response);
}).catch(function(error) {
console.log('Request failed', error)
});
Upvotes: 139
Reputation: 1720
Solution to resolve issue in Local env's
I had my front-end code running in http://localhost:3000 and my API(Backend code) running at http://localhost:5000
Was using fetch API to call the API. Initially, it was throwing "cors" error. Then added this below code in my Backend API code, allowing origin and header from anywhere.
let allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Headers', "*");
next();
}
app.use(allowCrossDomain);
However you must restrict origins in case of other environments like stage, prod.
Strictly NO for higher environments.
Upvotes: 21
Reputation: 41
You need to set cors header on server side where you are requesting data from. For example if your backend server is in Ruby on rails, use following code before sending back response. Same headers should be set for any backend server.
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, PUT, DELETE, GET, OPTIONS'
headers['Access-Control-Request-Method'] = '*'
headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization'
Upvotes: 4
Reputation: 31
Look at https://expressjs.com/en/resources/middleware/cors.html You have to use cors.
Install:
$ npm install cors
const cors = require('cors');
app.use(cors());
You have to put this code in your node server.
Upvotes: -3
Reputation: 690
This worked for me :
npm install -g local-cors-proxy
API endpoint that we want to request that has CORS issues:
https://www.yourdomain.com/test/list
Start Proxy:
lcp --proxyUrl https://www.yourdomain.com
Proxy Active
Proxy Url: http://www.yourdomain.com:28080
Proxy Partial: proxy
PORT: 8010
Then in your client code, new API endpoint:
http://localhost:8010/proxy/test/list
End result will be a request to https://www.yourdomain.ie/test/list without the CORS issues!
Upvotes: 30
Reputation: 351
If you are use nginx try this
#Control-Allow-Origin access
# Authorization headers aren't passed in CORS preflight (OPTIONS) calls. Always return a 200 for options.
add_header Access-Control-Allow-Credentials "true" always;
add_header Access-Control-Allow-Origin "https://URL-WHERE-ORIGIN-FROM-HERE " always;
add_header Access-Control-Allow-Methods "GET,OPTIONS" always;
add_header Access-Control-Allow-Headers "x-csrf-token,authorization,content-type,accept,origin,x-requested-with,access-control-allow-origin" always;
if ($request_method = OPTIONS ) {
return 200;
}
Upvotes: 3
Reputation: 1932
I know this is an older post, but I found what worked for me to fix this error was using the IP address of my server instead of using the domain name within my fetch request. So for example:
#(original) var request = new Request('https://davidwalsh.name/demo/arsenal.json');
#use IP instead
var request = new Request('https://0.0.0.0/demo/arsenal.json');
fetch(request).then(function(response) {
// Convert to JSON
return response.json();
}).then(function(j) {
// Yay, `j` is a JavaScript object
console.log(JSON.stringify(j));
}).catch(function(error) {
console.log('Request failed', error)
});
Upvotes: 10