'Access-Control-Allow-Origin' issue when API call made from React (Isomorphic app)
Javascriptnode.jsReactjsAxiosCorsJavascript Problem Overview
I'm running into an issue with my isomorphic JavaScript app using React and Express.
I am trying to make an HTTP request with axios.get when my component mounts
componentDidMount() {
const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then( res => {
//use res to update current state
})
}
I am getting a status 200 res from the API, but I am not getting any response data and getting an error in my console
XMLHttpRequest cannot load http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access.
However, if I make the request in my server.js
const url = 'http://ufc-data-api.ufc.com/api/v3/iphone/fighters/title_holders';
axios.get(url).then(res => {
//console.log(res);
});
It works fine and I get response data when the server starts. Is this an issue with the actual API or am I doing something wrong? If this was a CORS issue I'm guessing the request in server.js wouldn't work either? Thanks!
Javascript Solutions
Solution 1 - Javascript
CORS is a browser feature. Servers need to opt into CORS to allow browsers to bypass same-origin policy. Your server would not have that same restriction and be able to make requests to any server with a public API. https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Create an endpoint on your server with CORS enabled that can act as a proxy for your web app.
Solution 2 - Javascript
Use the google Chrome Extension called Allow-Control-Allow-Origin: *. It modifies the CORS headers on the fly in your application.
Solution 3 - Javascript
Fix Without Using External Proxy or Chrome Extension
CORS should be enable in server side! if you can not activate it on server (for example using external API) create a middleware React -> Middleware -> Orginal Server
.
-
Create a Node.js project (Middleware) and use below code in
app.js
.const express = require("express"); var cors = require('cors') const app = express(); app.use(cors()); const { createProxyMiddleware } = require('http-proxy-middleware'); app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080/', //original url changeOrigin: true, //secure: false, onProxyRes: function (proxyRes, req, res) { proxyRes.headers['Access-Control-Allow-Origin'] = '*'; } })); app.listen(5000);
This will pass the request http://localhost:5000/api/xxx
to original server (for example http://localhost:8080/api/xxx
), and returns the result to client.
-
Change client (React) to call proxy and get data without CORS error (you only need to change the port in url):
axios.get('http://localhost:5000/api/xxx', //proxy uri { headers: { authorization: ' xxxxxxxxxx' , 'Content-Type': 'application/json' } }).then(function (response) { console.log(response); });
-
run node project
node app.js
and react projectnpm start
.
Solution 4 - Javascript
I had the same problem. the other answers are correct but there is another solution. you can set response header to allow cross-origin access. according to this post you have to add the following codes before any app.get call:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
this worked for me :)
Solution 5 - Javascript
//install cors using terminal/command
$ npm install cors
//If your using express in your node server just add
var cors = require('cors');
app.use(cors())
//and re-run the server, your problem is rectified][1]][1]
**If you won't be understood then see below image**
Solution 6 - Javascript
You can use this code when using vs code on debugging mode.
> "runtimeArgs": ["--disable-web-security","--user-data-dir=~/ChromeUserData/"]
launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Chrome disable-web-security",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}",
"runtimeArgs": [
"--disable-web-security",
"--user-data-dir=~/ChromeUserData/"
]
}
]
}
Or directly run
Chrome --disable-web-security --user-data-dir=~/ChromeUserData/
Solution 7 - Javascript
I think the answer for your question is here
>To have Chrome send Access-Control-Allow-Origin in the header, just alias your localhost in your /etc/hosts file to some other domain, like: > >127.0.0.1 localhost yourdomain.com
Solution 8 - Javascript
I faced the same error today, using React with Typescript and a back-end using Java Spring boot, if you have a hand on your back-end you can simply add a configuration file for the CORS.
For the below example I set allowed origin to * to allow all but you can be more specific and only set url like http://localhost:3000.
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class AppCorsConfiguration {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
}
Solution 9 - Javascript
I was having the same problem with the fetch
command. A quick look at the docs from here tells us this:
> If the server you are requesting from doesn't support CORS, you should get an error in the console indicating that the cross-origin request is blocked due to the CORS Access-Control-Allow-Origin header being missing.
You can use no-cors mode to request opaque resources.
fetch('https://bar.com/data.json', {
mode: 'no-cors' // 'cors' by default
})
.then(function(response) {
// Do something with response
});
Solution 10 - Javascript
Create-React-App has a simple way to deal with this problem: add a proxy field to the package.json file as shown below
"proxy": "http://localhost:8081",
Solution 11 - Javascript
Because the server don't have CORS header, so you are not allowed to get the response.
This is header from API that I captured from Chrome brower:
Age:28
Cache-Control:max-age=3600, public
Connection:keep-alive
Date:Fri, 06 Jan 2017 02:05:33 GMT
ETag:"18303ae5d3714f8f1fbcb2c8e6499190"
Server:Cowboy
Status:200 OK
Via:1.1 vegur, 1.1 e01a35c1b8f382e5c0a399f1741255fd.cloudfront.net (CloudFront)
X-Amz-Cf-Id:GH6w6y_P5ht7AqAD3SnlK39EJ0PpnignqSI3o5Fsbi9PKHEFNMA0yw==
X-Cache:Hit from cloudfront
X-Content-Type-Options:nosniff
X-Frame-Options:SAMEORIGIN
X-Request-Id:b971e55f-b43d-43ce-8d4f-aa9d39830629
X-Runtime:0.014042
X-Ua-Compatible:chrome=1
X-Xss-Protection:1; mode=block
No CORS header in response headers.
Solution 12 - Javascript
I don't know if this will help but I was getting the same error when remote debugging a react-native application. I was running the debugger on 192.168.x.x:8081. I read a little bit on this [Cross-Origin Resource Sharing (CORS)][1] to educate myself on what CORS is. (I'm a beginner) and changed my URL from IP:8081 to localhost:8081 and my issue was resolved.
[1]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/ "MDN link"
Solution 13 - Javascript
In my case I was getting the CORS error even after enabling it on server side. The issue was url. localhost:4001/todos
I forgot to prepend the 'http'.
http://localhost:4001/todos //correct way
You don't have to deal with it on client side. Just need the following steps:
Step 1:
npm install cors
Step 2:
//express-server.js
...
const cors = require('cors');
app.use(cors());
Done!
Solution 14 - Javascript
This is a common issue occurs when you try to call an endpoint via your react app because react app is running on localhost:3000 and apis are on different servers.
to rectify this error install 'http-proxy-middleware'
npm i http-proxy-middleware
or
yarn add http-proxy-middleware
after installation create a setupProxy.js in your src folder
and follow below code
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/getDetails', //this is your api
createProxyMiddleware({
target:'http://10.0.0.20:9000/getDetails', //this is your whole endpoint link
changeOrigin: true,
})
);
app.use(
'/getproducts', //this is your api
createProxyMiddleware({
target:'http://10.0.0.20:9000/getproducts', //this is your whole endpoint link
changeOrigin: true,
})
);
};
you can add as many api as you want in app.use. and then just normally call the api
axios.get('http://10.0.0.20:9680/getDetails')
for more details check below link Porxying API requests in Development in React JS
Solution 15 - Javascript
Add proxy to package.json file and keep the remaining part of url in the fetch itself.
eg.,
In package.json file, "proxy" : "https://www.google.com";, //add your own website link
In App.js file const response = await fetch(./...(as per your own))