46

This may be a duplicate, but I havent found a thread relating specifically to my issue.

I am making the following API call:

const config = {
  headers: {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,PATCH,OPTIONS"
  }
};

const {
  data: { ip }
} = await axios.get("https://api.ipify.org?format=json", config);

And this throws an error:

Access to XMLHttpRequest at 'https://api.ipify.org/?format=json' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

When I deploy my app to Heroku, the API call works as expected. However it does not work when developing on my local machine. Not sure what I'm missing here.

Mike K
  • 5,940
  • 7
  • 37
  • 87
  • are you using only react or maybe something else? – Newell Jul 12 '19 at 14:52
  • React frontend, Node backend – Mike K Jul 12 '19 at 14:57
  • 4
    This has been asked and answered over and over again. TL;DR **a script at `domain-a` can't fetch something at `domain-b` unless `server-b` allows it**. Settings CORS options in the `domain-a` script won't grant you more permissions, only a change at `server-b` will. – Nino Filiu Jul 12 '19 at 15:10
  • Possible duplicate of [Why does my JavaScript code get a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error when Postman does not?](https://stackoverflow.com/questions/20035101/why-does-my-javascript-code-get-a-no-access-control-allow-origin-header-is-pr) – Nino Filiu Jul 12 '19 at 15:10
  • 1
    @NinoFiliu So in this case domain-b allows Heroku domains, but disallows localhost? – Mike K Jul 12 '19 at 15:14
  • `domain-a = http://localhost:3000` and `domain-b = https://api.ipify.org`. Yes, possibly. – Nino Filiu Jul 12 '19 at 15:15

9 Answers9

50

if you are building your rest api in nodejs. Follow the folowing simple steps

Stop the Node.js server.

npm install cors --save

Add following lines to your server.js or index.js

var cors = require('cors')

app.use(cors()) // Use this after the variable declaration

Now try to make your api call on the client side and it should work

  • 5
    The author of the post specified that he's pulling data from ipify.org, which is a privately owned domain. The author does not own this company/website/api, so this solution makes no sense, as this solution would work for a different scenario where the author would actually have control over the API service – Christopher Francisco Dec 15 '20 at 13:33
  • Even if this is an incorrect answer, in my opinion that's not the reason for deletion. As we can see from upvotes some people found it useful. – Mike Szyndel Dec 15 '20 at 21:17
  • In my case I did this in the back-end.Still its not working. I am using Node as back-end and React in the front-end. The front-end code looks like tthis. `export default axios.create({ baseURL: "http://localhost/3001/api/v1/restaurants" });` And in other component I am fetching like this `const response = await RestaurantApi.get("/") ; ` I am still getting the error. – bad_coder9042093 Jun 20 '21 at 11:09
21

After many days finally I got a solution . Instead of using CORS simply like this

const cors = require('cors');

app.use(cors());

in your server index.js using CORS option will solve the issue and now you can pass cookies or other credentials

const cors = require('cors');
const corsOptions ={
    origin:'http://localhost:3000', 
    credentials:true,            //access-control-allow-credentials:true
    optionSuccessStatus:200
}
app.use(cors(corsOptions));
VASU TIWARI
  • 283
  • 4
  • 6
10

You can't really fetch data from servers, with a different hostname, that don't have a CORS policy to allow request from your domain.

In simpler words, localhost can't call ipify.org unless it allows it. It seems like it doesn't, and I assume that server is not managed by you. So your only option is to go with a reverse proxy. You can read how to create an http proxy with node here.

What you need is for your app to be served on a fake/stubbed host, rather than localhost:

local.development.ipify.org -> proxies to localhost:3000

That way, when you make your api call, you are under the same domain as ipify.org, and you won't get any CORS issues.

Christopher Francisco
  • 14,798
  • 28
  • 86
  • 202
  • Can you please explain how Node is relevant here? The call works on the Heroku app, but does not work on my localhost. Do I need to create an http proxy with React? Or it has to be node? My Node backend isn't even reached at any point, because the axios call from the frontend fails before attempting to communicate with the backend – Mike K Jul 12 '19 at 15:02
  • The important bit is the reverse proxy. Node isn't really relevant, you can use any tool you want to create your reverse proxy, or even an Nginx. What you want is for your app not to be served on localhost, but on a stubbed subdomain. I'll update my answer. – Christopher Francisco Jul 12 '19 at 15:19
7

This article solved my problem in no time.

The quickest fix you can make is to install the moesif CORS extension . Once installed, click it in your browser to activate the extension. Make sure the icon’s label goes from “off” to “on“

5

First of all in your back-end app like express app you have to enable cors

like :

  1. install cors running the command npm i cors
  2. then go to your server.js or app.js or index.js file and add
  • var cors = require('cors');
  • app.use(cors())

3.cors will enable your client or front-end app to access your back-end routes. finally go to your routes and inside get route paste the following lines

  • router.get("/", (req, res) => {
  • res.setHeader("Access-Control-Allow-Origin", "*")
  • res.setHeader("Access-Control-Allow-Credentials", "true");
  • res.setHeader("Access-Control-Max-Age", "1800");
  • res.setHeader("Access-Control-Allow-Headers", "content-type");
  • res.setHeader( "Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, PATCH, OPTIONS" );
  • });

` I also suffered for 2 hours facing this issue and i resolved my problem like this.So hope this will help you

Ruman
  • 738
  • 9
  • 8
3

What you seem to be trying to do is telling the server that it should use the CORS policies that you have specified in your Axios call. This is simply not how things work - the server defines its own CORS policies, and you simply must conform to them. If the server that you are trying to access does not support http://localhost:3000 in its CORS policies, you cannot use that origin with the API.

If the server is yours, look into the cors package and configure it to allow localhost:3000as an origin. If you do not own the server, you can't really change any CORS policies without asking the server owner if they would be willing to do so.

3

Go to your package.json file and add: "proxy": "your-api-url" but only the beginning/base, as an example if you are using the pokemon api, you just have to set "proxy" : "https://pokeapi.co/api/v2" and in your service file you can use axios with the path you need:

axios.get("/pokemon?limit=1000")
  .then(response => {
    resolve(response.data.results);
  })
Mike Szyndel
  • 10,124
  • 7
  • 44
  • 61
2

This may be due to the POST request from react app in development mode. You can bypass the CORS policy in development mode by the adding following line of code in your ' file.

{
    ...
    "proxy": "http://localhost:3000",
    ...
}
Shmili Breuer
  • 3,684
  • 1
  • 18
  • 23
0

I was getting this issue only on crome browser and on crome browser I had multilogin extension. When I delete this extension, this issue is fixed.

rohitbansal2009
  • 31
  • 1
  • 1
  • 6