Ошибка cors react

CORS actually stands for Cross-Origin Resource Sharing and is a mechanism that allows services to communicate with each other.

CORS actually stands for Cross-Origin Resource Sharing and is a mechanism that allows services to communicate with each other. You must have come across the infamous error that bothered almost every single person dabbling with web development. I came across it as well and was utterly frustrated with it.

SOP

Same Origin Policy (SOP) is a mechanism implemented by modern web browsers that block your application from requesting data that lives on a different URL. If you make a request that lives on a different URL or origin, the browser will block this data from being shared in your application. And to make matters worse it will throw these really vague errors that make it almost impossible for newbies to debug.

Client and Server

I have used the demo example of the express server taken from the official documentation. The application is running on port 4000 and we have only one route / that responds with a string ‘Hello World!’

const express = require('express')
const app = express()
const port = 4000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

On the client side, we are using a freshly generated React project that makes a request to our server and logs the output to the console. We’re using axios to help us make that request.

import axios from 'axios'

function App() {

  const fetchData = async () => {
    const resp = await axios.get('http://localhost:4000')
    console.log(resp)
  }
  
  fetchData()

  return (
    <>
    </>
  );
}

export default App;

But when you check the console of your client application you can see that some things didn’t go exactly as planned.

Does the screenshot below look familiar to you? You most likely came across it when trying to write a React application that interacts with your server

cors error

If yes then keep on reading this article as we’ll quickly get rid of it. Let’s start by translating the error into plain English so that we could be on the same page when it comes to understanding why the applied fix works.

Origin, in this case, is defined as a combination of URI, hostname and port in the following format SCHEME://HOSTNAME:PORT. In the example of my application, my client is running on

http://localhost:3000

but my server is running at

http://localhost:4000

Solution

The solution to this problem needs to be implemented on the server. We will make use of the CORS middleware to help us with that. Let’s start by installing it on our server. Run the following command in the root directory of your server application

$ npm install cors

We can now go ahead and use it in our application.

const express = require('express')
const app = express()
const cors = require('cors')
const port = 4000

app.use(cors())

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

Now restart the server and refresh your client in the browser, you will see that the error went away and the response is printing in the console as expected.

response

In our case, we have taken the easy way out and enabled CORS requests across all of the routes in our application. If you’re working on a slightly more complicated project then you should take a look at the official documentation and check for yourself on how to best handle this error.

Avatar photo

Hello! I’m Dawid. I’m a full-stack developer with a couple of years of experience under my belt. I spent most of my career working with React. Now it’s time to pass the knowledge onto somebody else!

Table of Contents

In the previous article, I have explained how to deploy a Node.js application to Heroku.
In this tutorial, we will be making use of the endpoint created there and see if we can use it in our React project.

Project Setup

Let’s create a React project using the following command:

1npx create-react-app react-cors

Now update the App.js with the following code:

App.js

1import { useEffect, useState } from "react"

2import "./App.css"

3

4function App() {

5 const [message, setMessage] = useState("")

6 useEffect(() => {

7 fetch("https://nodejs-using-github.herokuapp.com/")

8 .then(response => response.json())

9 .then(data => {

10 setMessage(data.message)

11 })

12 .catch(err => console.log(err))

13 }, [])

14 return <div className="App">{message ? message : "Loading.."}</div>

15}

16

17export default App

Here we have a local state called message, which we show to the user.
If the message is empty, then we display them with a loading text.
When the component is mounted (useEffect), we make a call to the API endpoint and fetch the message.

Now let’s run this and see if it works:

loading

You will see that only «Loading..» text is displayed and the message never loads.
If we inspect the page and see the console, we will see the following error:

Access to fetch at 'https://nodejs-using-github.herokuapp.com/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

cors error

In the next sections, we will see what is CORS and how to fix this error.

What is CORS (Cross-Origin Resource Sharing)?

CORS stands for Cross-Origin Resource Sharing,
which is an HTTP header based mechanism that helps the server to tell the browser,
from which all domain requests can be made (except the same domain).

That is, in our case, the Node.js server hosted at https://nodejs-using-github.herokuapp.com/,
does not tell the browser that request can be made from http://localhost:3000.

When this happens, your browser will throw an error as seen earlier.

Why CORS (Cross-Origin Resource Sharing)?

The next question that would come to your mind is why do we really need this mechanism.
Imagine you are logged into your bank account or any social media website, then you visit a malicious website.
This malicious website could run some scripts in the background to make API calls to your banking or social media to get your personal details.

To prevent this, your browser checks if the request to the banking or social media server can be made from the malicious website and throws the CORS error.

So CORS exists to share certain resources between trusted third-parties (across different origins/domains), hence the name Cross-Origin Resource Sharing.

How to configure CORS in Node.js

Since we are clear about what and why is CORS required, let’s see how to enable CORS in the Node.js application.

You may clone the Node.js code from this repo.
Once the project is cloned, open it in your code editor and install cors package.

Now open index.js and update it with the following code:

index.js

1const express = require("express")

2const cors = require("cors")

3const app = express()

4const port = process.env.PORT || 3000

5

6const whitelist = ["http://localhost:3000"]

7const corsOptions = {

8 origin: function (origin, callback) {

9 if (!origin || whitelist.indexOf(origin) !== -1) {

10 callback(null, true)

11 } else {

12 callback(new Error("Not allowed by CORS"))

13 }

14 },

15 credentials: true,

16}

17app.use(cors(corsOptions))

18

19app.get("/", (req, res) => {

20 res.send({ message: "Hello World!" })

21})

22

23app.listen(port, () => {

24 console.log(`Example app listening at Port: ${port}`)

25})

Here we check if the origin (client’s domain) is in the whitelist, then we tell the clients that requests can be made.
If it is not in the list then we throw an error saying the client is not allowed to make CORS requests to this server.

The domain should not have any trailing slashes (/)

We can deploy the changes to Heroku and see if this works.

Now if you reload your page, you should be able to see the message.

cors success

You will also see that a response header called Access-Control-Allow-Origin has been added with the value http://localhost:3000.

Making CORS domains configurable

If you have multiple client origins to be connected to you, and you want them to be configurable, you can do so by using environment variables:

index.js

1const express = require("express")

2const cors = require("cors")

3const app = express()

4const port = process.env.PORT || 3000

5

6const domainsFromEnv = process.env.CORS_DOMAINS || ""

7

8const whitelist = domainsFromEnv.split(",").map(item => item.trim())

9

10const corsOptions = {

11 origin: function (origin, callback) {

12 if (!origin || whitelist.indexOf(origin) !== -1) {

13 callback(null, true)

14 } else {

15 callback(new Error("Not allowed by CORS"))

16 }

17 },

18 credentials: true,

19}

20app.use(cors(corsOptions))

21

22app.get("/", (req, res) => {

23 res.send({ message: "Hello World!" })

24})

25

26app.listen(port, () => {

27 console.log(`Example app listening at Port: ${port}`)

28})

Testing environment variables locally

To test environment variables locally, you can install the package called dotenv:

Now create a file called .env in the root directory of your project with the domains:

1CORS_DOMAINS = http://localhost:3000, http://localhost:3001, https://example.com

Update index.js to use the dotenv package:

index.js

1const express = require("express")

2const cors = require("cors")

3const app = express()

4const port = process.env.PORT || 3000

5

6if (process.env.NODE_ENV !== "production") {

7 require("dotenv").config()

8}

9

10const domainsFromEnv = process.env.CORS_DOMAINS || ""

11

12const whitelist = domainsFromEnv.split(",").map(item => item.trim())

13

14const corsOptions = {

15 origin: function (origin, callback) {

16 if (!origin || whitelist.indexOf(origin) !== -1) {

17 callback(null, true)

18 } else {

19 callback(new Error("Not allowed by CORS"))

20 }

21 },

22 credentials: true,

23}

24app.use(cors(corsOptions))

25

26app.get("/", (req, res) => {

27 res.send({ message: "Hello World!" })

28})

29

30app.listen(port, () => {

31 console.log(`Example app listening at Port: ${port}`)

32})

Here we made sure that .env files are loaded only in non-production environments.
It is recommended to store the configurations in the server host rather than in .env files for production.

Remember to add .env* to the .gitignore file so that you don’t accidentally push them to the repo.

Configuring environment files in heroku

With our latest code, we can configure environment files in the heroku settings:

heroku env

Go to your project settings and click on «Reveal Config Vars». Now you can provide the key and values here and click on «Add»

heroku config vars

Once added, you can push your changes and see if the changes work.

If you have liked article, stay in touch with me by following me on twitter.

In Part 2 of this series, we’ll be making a REST API call from our React project to a service that has some CORS policies implemented. In this particular example, we’ll make REST API calls to xkcd’s API.

Make REST API calls to xkcd

What is xkcd?

xkcd is a webcomic series created by American author Randall Munroe. You can find the awesome comics here.

xkcd has an API?

Yes, it does indeed have an API.
You can find the great and concise API docs here.

What are we going to do?

We’ll make REST API calls to one of my favorite comic strips that has an ID of 327, i.e. our endpoint will be https://xkcd.com/327/info.0.json. This will return JSON data about that particular comic strip.

Let’s try calling it!

OK, so the implementation should be fairly simple. We made our REST API call to the Random User Generator API in our previous article — we just have to switch around the endpoint URL, right?

//const restEndpoint = "https://randomuser.me/api/";
const restEndpoint = "https://xkcd.com/327/info.0.json";

Enter fullscreen mode

Exit fullscreen mode

OK that was super easy! Now let’s refresh our React page.

Alt Text

…? Access to fetch at blah blah from origin bleh bleh has been blocked by CORS policy …. say what now???

Well, it looks like the response didn’t render. And there seems to be a whole lot of red text in the console…_(┐「ε:)_

That error we see in the console is well known as the CORS Error. Basically, resources that lie on xkcd’s domain cannot be requested from another domain (i.e. our front-end React App).

Alt Text

There are several ways we can overcome this issue:

  1. Make REST API calls from the same domain as xkcd
  2. Edit the CORS settings of xkcd’s server
  3. Make REST API calls from our own backend server

We can quickly experience method 1 if we navigate to any page on xkcd, and run the following code in the console.

fetch('https://xkcd.com/327/info.0.json')
  .then(response => response.json())
  .then(data => console.log(data));

Enter fullscreen mode

Exit fullscreen mode

Alt Text

The REST API request is being made on the same domain, so we don’t run into any CORS errors. But it’s highly unlikely that xkcd will host our React App on their site for us, so this isn’t a realistic approach.

Method 2 again is unrealistic, since we don’t have permission to access the settings of xkcd’s server ¯(ツ)

Method 3 is achievable by either setting up your own server and making requests from it, or using a services such as Zapier or Power Automate to make the requests for us.

In this article, we’ll proceed with Method 3 by setting up a backend server using Express, which will act as a proxy to make REST API calls to xkcd.

Set up Express

What is Express?

Express is a back-end web application framework for Node.

How will we use Express?

In this article, we’ll treat Express as a tool for creating custom endpoints that our front-end React App can make calls to. When we make requests to these custom endpoints, the Express server will make REST API calls to our desired 3rd party service endpoint, receive the response, and then route the response back to our React App.

If that was a bit hard to grasp, think of it like ordering food at a nice restaurant. If we (front-end App) go directly to the kitchen and order food directly to the chef (3rd party service), we’ll be scolded for bad manners (CORS errors). What we need to do is order food to the server (Express App). The server (Express App) will take our order, walk to the kitchen, and request for the food to the chef (3rd party service). After some time, the chef (3rd party service) will respond by giving the server (Express App) back a plate of food. The server (Express App) then carries the plate back to the table so that we (front-end App) can consume it.

Set up Express

OK, so let’s go ahead to set up Express. This is basically a new node project with the Express dependencies installed. We’ll want this project to be in a separate location from our React App, so let’s navigate back up to our myproject directory, create a new directory called backend, and navigate into it. Since the terminal we were using is running the React app, go ahead to use the commands in a new terminal window.

mkdir backend
cd backend

Enter fullscreen mode

Exit fullscreen mode

From here we’ll follow the Express installation tutorial to make our Express project.

npm init

Enter fullscreen mode

Exit fullscreen mode

You’ll be asked a number of questions but you can skip through them by hitting enter until it’s finished.

Continue to install some dependencies.

npm install express node-fetch cors

Enter fullscreen mode

Exit fullscreen mode

Finally, create a JavaScript file to work on — we’ll call ours server.js.

touch server.js

Enter fullscreen mode

Exit fullscreen mode

Alt Text

Set up the Express code

We’ll use this code for server.js

const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch');

const PORT = 5000;
const app = express();

app.use(cors());
const corsOptions = {
    origin: "http://localhost:3000"
};

const requestEndpoint = "https://xkcd.com/327/info.0.json";

// This function runs if the http://localhost:5000/getData endpoint
// is requested with a GET request
app.get('/getData', cors(corsOptions), async (req, res) => {
    const fetchOptions = {
        method: 'GET'
    }
    const response = await fetch(requestEndpoint, fetchOptions);
    const jsonResponse = await response.json();
    res.json(jsonResponse);
});

app.listen(PORT, () => {
    console.log(`Example app listening at http://localhost:${PORT}`);
});

Enter fullscreen mode

Exit fullscreen mode

So, let’s go through the code.

We first set our port to 5000, as we need it to be separate from the port we use on our front-end React App, which was defaulted to port 3000.

const PORT = 5000;

Enter fullscreen mode

Exit fullscreen mode

Express commonly uses routing that defines how the server’s endpoints will respond to our front-end React App’s requests. In this case, we’ve defined how the server will react when the endpoint http://localhost:5000/getData is accessed with a GET request.

app.get('/getData', cors(corsOptions), async (req, res) => {
  //...
});

Enter fullscreen mode

Exit fullscreen mode

But by default, our Express server will return CORS errors if accessed from our front-end React App that lies on a different domain (port). By setting up some CORS options, we allow requests from port 3000 to access our resources that lie on http://localhost:5000/getData.

app.use(cors());
const corsOptions = {
    origin: "http://localhost:3000"
};

app.get('/getData', cors(corsOptions), async (req, res) => {
  //...
});

Enter fullscreen mode

Exit fullscreen mode

If we were to access http://localhost:5000/getData with a GET request from our React App, Express will run the related function, which in this case would be a fetch request to the xkcd REST API endpoint. As this request is made from the server side, it does not run in to any CORS errors. The response from xkcd is obtained, and returned back to our React App through the res.json() method.

const fetchOptions = {
    method: 'GET'
}
const response = await fetch(requestEndpoint, fetchOptions);
const jsonResponse = await response.json();
res.json(jsonResponse);

Enter fullscreen mode

Exit fullscreen mode

OK, now that’s ready, let’s start running the express server!

node server.js

Enter fullscreen mode

Exit fullscreen mode

We can quickly see if it’s running successfully by accessing http://localhost:5000/getData through the browser. We should see the JSON response being displayed.

Alt Text

OK, so it looks like the Express App is making successful REST API calls to https://xkcd.com/327/info.0.json. Note that if we want to make any changes to server.js, we should restart the App to see the changes take place.

Let’s leave the Express server running, and return back to our React code so that it points to the Express App rather than directly to the xkcd server.

Update the React code

There isn’t much to do here, except for updating our REST endpoint to our Express server instead of the xkcd endpoint.

// const restEndpoint = "https://xkcd.com/327/info.0.json";
const restEndpoint = "http://localhost:5000/getData";

Enter fullscreen mode

Exit fullscreen mode

Refresh the browser, and let’s see if we’ve managed to bypass the CORS error.

Alt Text

Great! The REST API response has successfully rendered onto our HTML, and there are no CORS errors in our console.

And with that, we’ve managed to successfully avoid CORS errors to make REST API calls to xkcd by using our Express server as a proxy!

Next steps

In the next part of the series, we’ll make a REST API call to a Web Database service, Kintone, which will challenge us to our next issue.

                   _人人人人人人人人人_
                   > AUTHENTICATION <
                    ̄Y^Y^Y^Y^Y^Y^Y^Y ̄
                   (__/) 
                   (•ㅅ•) 
                   /つ つ

Enter fullscreen mode

Exit fullscreen mode

Getting this error in your React and/or Express app?

No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

You’ve run afoul of the Same Origin Policy – it says that every AJAX request must match the exact host, protocol, and port of your site. Things that might cause this:

  • Hitting a server from a locally-served file (a request from file:///YourApp/index.html to http://api.awesome.com)
  • Hitting an external API (a request from http://yourapp.com to http://api.awesome.com).
  • Hitting an internal API (a request from http://yourapp.com to http://api.yourapp.com).
  • Hitting a different port on the same host (webapp is on http://localhost:3000, API is http://localhost:4000)
  • Requesting over http from https or vice-versa (requesting https://yourapp.com from http://yourapp.com)

To be clear, this is not a React error. It afflicts all web apps equally, and most of the fixes we’ll look at below are actually modifying the server or the browser.

How to Fix It

Here are a few ways to solve this problem:

CORS (Cross-Origin Resource Sharing) is a way for the server to say “I will accept your request, even though you came from a different origin.” This requires cooperation from the server – so if you can’t modify the server (e.g., if you’re using an external API), this approach won’t work.

Modify the server to add the header Access-Control-Allow-Origin: * to enable cross-origin requests from anywhere (or specify a domain instead of *). This should solve your problem.

How to Enable CORS on Express

If you’re using Express, the easiest way to enable CORS is with the cors library.

You just need to install it in your Express project with npm install cors, then require it and add it as a middleware:

var express = require('express');

var cors = require('cors');

var app = express();


app.use(cors());

Two important things to know here:

  • Express runs its middleware in order. So make sure this app.use code runs before you set up your routes.
  • By default, the cors library will allow requests from any origin. This can open you up to security problems and abuse.

For production use, it’s best not to allow all origins. Instead, create a whitelist of allowed domains, and check each request against the whitelist. Here’s how:

var whitelist = ['http://example1.com', 'http://example2.com']
var corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}


app.use(cors(corsOptions));
Second choice: Proxy Server

If you can’t modify the server, you can run your own proxy. And this proxy can return the Access-Control-Allow-Origin header if it’s not at the Same Origin as your page.

Instead of sending API requests to some remote server, you’ll make requests to your proxy, which will forward them to the remote server. Here are a few proxy options.

Third choice: JSONP (requires server support)

If CORS and the proxy server don’t work for you, JSONP may help. You essentially make a GET request with a callback parameter:

(get) http:

The server will wrap the JSON reply in a function call to your callback, where you can handle it:

foo({"your": "json", here: true})

There are some downsides, notably that JSONP only supports GET requests and that you still need a cooperative server.

Dev-Only: Disable Same Origin

If this is only for development or learning purposes, the easiest thing to do is to disable the Same Origin Policy in your browser. Be aware that if you do this, you’re opening your browser up to security risks. Follow these instructions:

  • Chrome
  • Firefox

This is more of a last resort. Modifying the server to support CORS or running a proxy are the best approaches.

Armed and Dangerous

You’re all set now to tackle any Access-Control-Allow-Origin errors that come your way!

Access-Control-Allow-Origin: Dealing with CORS Errors in React and Express was originally published by Dave Ceddia at Dave Ceddia on July 11, 2018.

Dave is a Software Engineer in the Boston area and writes about AngularJS and other JavaScript things over at daveceddia.com

Getting this error in your React and/or Express app?

No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

You’ve run afoul of the Same Origin Policy – it says that every AJAX request must match the exact host, protocol, and port of your site. Things that might cause this:

  • Hitting a server from a locally-served file (a request from file:///YourApp/index.html to http://api.awesome.com)
  • Hitting an external API (a request from http://yourapp.com to http://api.awesome.com).
  • Hitting an internal API (a request from http://yourapp.com to http://api.yourapp.com).
  • Hitting a different port on the same host (webapp is on http://localhost:3000, API is http://localhost:4000)
  • Requesting over http from https or vice-versa (requesting https://yourapp.com from http://yourapp.com)

To be clear, this is not a React error. It afflicts all web apps equally, and most of the fixes we’ll look at below are actually modifying the server or the browser.

How to Fix It

Here are a few ways to solve this problem:

CORS (Cross-Origin Resource Sharing) is a way for the server to say “I will accept your request, even though you came from a different origin.” This requires cooperation from the server – so if you can’t modify the server (e.g., if you’re using an external API), this approach won’t work.

Modify the server to add the header Access-Control-Allow-Origin: * to enable cross-origin requests from anywhere (or specify a domain instead of *). This should solve your problem.

How to Enable CORS on Express

If you’re using Express, the easiest way to enable CORS is with the cors library.

You just need to install it in your Express project with npm install cors, then require it and add it as a middleware:

var express = require('express');

var cors = require('cors');

var app = express();


app.use(cors());

Two important things to know here:

  • Express runs its middleware in order. So make sure this app.use code runs before you set up your routes.
  • By default, the cors library will allow requests from any origin. This can open you up to security problems and abuse.

For production use, it’s best not to allow all origins. Instead, create a whitelist of allowed domains, and check each request against the whitelist. Here’s how:

var whitelist = ['http://example1.com', 'http://example2.com']
var corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}


app.use(cors(corsOptions));
Second choice: Proxy Server

If you can’t modify the server, you can run your own proxy. And this proxy can return the Access-Control-Allow-Origin header if it’s not at the Same Origin as your page.

Instead of sending API requests to some remote server, you’ll make requests to your proxy, which will forward them to the remote server. Here are a few proxy options.

Third choice: JSONP (requires server support)

If CORS and the proxy server don’t work for you, JSONP may help. You essentially make a GET request with a callback parameter:

(get) http:

The server will wrap the JSON reply in a function call to your callback, where you can handle it:

foo({"your": "json", here: true})

There are some downsides, notably that JSONP only supports GET requests and that you still need a cooperative server.

Dev-Only: Disable Same Origin

If this is only for development or learning purposes, the easiest thing to do is to disable the Same Origin Policy in your browser. Be aware that if you do this, you’re opening your browser up to security risks. Follow these instructions:

  • Chrome
  • Firefox

This is more of a last resort. Modifying the server to support CORS or running a proxy are the best approaches.

Armed and Dangerous

You’re all set now to tackle any Access-Control-Allow-Origin errors that come your way!

Access-Control-Allow-Origin: Dealing with CORS Errors in React and Express was originally published by Dave Ceddia at Dave Ceddia on July 11, 2018.

Dave is a Software Engineer in the Boston area and writes about AngularJS and other JavaScript things over at daveceddia.com

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Ошибка cors javascript
  • Ошибка corona error message
  • Ошибка coreldraw 2020 unable to load vgcore error code 127
  • Ошибка corel unable to load vgcore error code 127
  • Ошибка copyfile failed with 32 easy anti cheat

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии