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

222,625

Solution 1

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

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 3

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

Solution 4

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

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

Share:
222,625
Scott Davidson
Author by

Scott Davidson

Updated on November 14, 2021

Comments

  • Scott Davidson
    Scott Davidson over 2 years

    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!

  • azium
    azium about 6 years
    @Todd security should always come before convenience. Luckily provisioning proxy servers can be a 5 minute exercise. Additionally there are proxy services that expose this type of functionality already but only allow so many free requests. Setting up your own proxy is worth the extremely minimal effort.
  • Sagar Gautam
    Sagar Gautam almost 6 years
    I've got the same problem and i've read the docs you have mentioned above still don't get idea of CORS can you elaborate it, please
  • azium
    azium almost 6 years
    @SagarGautam Can you make a new stackoverflow question and mention everything you're having trouble understanding, then comment here with the link to your post? I'll be happy to answer
  • Sagar Gautam
    Sagar Gautam almost 6 years
    I've asked question here please have a look stackoverflow.com/questions/51701630/…
  • chk.buddi
    chk.buddi over 5 years
    I have the same issue.In my case I can create records from desktop computer web browser but cannot create through my iPhone web browser.
  • Luv33preet
    Luv33preet over 4 years
    use it for testing purposes only. Your users are not going to enable plugins on their browsers to use your website
  • Lucas Andrade
    Lucas Andrade over 4 years
    It's also available for Firefox.
  • istovatis
    istovatis about 4 years
    However keep in mind that a response for a no-cors request has a response type of 'opaque', which means that you won't be able to read the data returned from the server
  • Michael Freidgeim
    Michael Freidgeim about 4 years
    Your answer will work only if a client tries to access localhost for local development. OP asked about access to real server.
  • Michael Freidgeim
    Michael Freidgeim about 4 years
    Sorry, you are right, I missed reference to localhost in error message.
  • Kviz Majster
    Kviz Majster about 3 years
    Do you have idea how to make vsc use this configuration automatically when i run "npm start" ? I must use F5 to make chrome use launch.json. Thanx