'Access-Control-Allow-Origin' issue when API call made from React (Isomorphic app)

Javascriptnode.jsReactjsAxiosCors

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

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

  1. 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);
    });
    
  2. run node project node app.js and react project npm 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**

https://i.stack.imgur.com/Qeqmc.png

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionScott DavidsonView Question on Stackoverflow
Solution 1 - JavascriptaziumView Answer on Stackoverflow
Solution 2 - JavascriptColleen PurcellView Answer on Stackoverflow
Solution 3 - Javascriptalireza ranjbaranView Answer on Stackoverflow
Solution 4 - Javascriptarash nadaliView Answer on Stackoverflow
Solution 5 - JavascriptHandyPawanView Answer on Stackoverflow
Solution 6 - JavascriptAhmad AghazadehView Answer on Stackoverflow
Solution 7 - JavascriptPablo DardeView Answer on Stackoverflow
Solution 8 - JavascriptLoup OllivierView Answer on Stackoverflow
Solution 9 - JavascriptYigit AlparslanView Answer on Stackoverflow
Solution 10 - JavascriptPiotrView Answer on Stackoverflow
Solution 11 - JavascriptThanh NguyenView Answer on Stackoverflow
Solution 12 - JavascriptMinginaView Answer on Stackoverflow
Solution 13 - JavascriptAnil SinghView Answer on Stackoverflow
Solution 14 - JavascriptAniket DeshpandeView Answer on Stackoverflow
Solution 15 - JavascriptnewbieView Answer on Stackoverflow