'Access-Control-Allow-Origin' Issue When Api Call Made from React (Isomorphic App)

'Access-Control-Allow-Origin' Issue When Api Call Made from React (Isomorphic App)

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 = '
  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  
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin ' is therefore not allowed access.

However, if I make the request in my server.js

const url = '
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!

1

15 Answers

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.

Create an endpoint on your server with CORS enabled that can act as a proxy for your web app.

5

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.

  1. 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: ' //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 to original server (for example ), and returns the result to client.

  1. Change client (React) to call proxy and get data without CORS error (you only need to change the port in url):

    axios.get(' //proxy uri
    {
       headers: {
          authorization: ' xxxxxxxxxx' ,
          'Content-Type': 'application/json'
       } 
    }).then(function (response) {
       console.log(response);
    });
    
  2. run node project node app.js and react project npm start.

0

Use the google Chrome Extension called Allow-Control-Allow-Origin: *. It modifies the CORS headers on the fly in your application.

2

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 :)

        //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**

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": "",
      "webRoot": "${workspaceFolder}",
      "runtimeArgs": [
        "--disable-web-security",
        "--user-data-dir=~/ChromeUserData/"
      ]
    }
  ]
}

Or directly run

Chrome --disable-web-security --user-data-dir=~/ChromeUserData/

1

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

2

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 .

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;
    }
}
0

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": "",

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(' {
  mode: 'no-cors' // 'cors' by default
})
.then(function(response) {
  // Do something with response
});
1

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.

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) 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.

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'.

 //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!

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:' //this is your whole endpoint link
          changeOrigin: true,
        })
      );


    app.use(
        '/getproducts', //this is your api
        createProxyMiddleware({
          target:' //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(')

for more details check below link Porxying API requests in Development in React JS

Add proxy to package.json file and keep the remaining part of url in the fetch itself.

eg.,

In package.json file, "proxy" : "", //add your own website link

In App.js file const response = await fetch(./...(as per your own))

Marcus Vance
Author

Marcus Vance

Marcus Vance is a cybersecurity auditor and technology writer dedicated to educating the public about online safety, data privacy regulations, enterprise security, and emerging cyber threats.