When developing an application using Vite with React and Express, the front-end runs on http://localhost:5173, and the back-end runs on http://localhost:5000, which involves a scenario of separate front-end and back-end development.

Problem Description

When using the fetch() method for a POST request test on the front-end, an error indicating that access is blocked by the CORS policy keeps occurring.

06351c02-dd8c-4b9d-a2a3-167b2a15c282.webp

Here is an example of the front-end code:

// Front-end code
const handleLogin = async (event) => {
const form = event.currentTarget;
event.preventDefault();
if (form.checkValidity() === false) {
event.stopPropagation();
setValidated(true);
return;
}
try {
const response = await fetch("http://localhost:5000/user/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ username, password }),
});
const result = await response.json();
if (result.success) {
setAlert({ show: true, message: "Login successful!", variant: "success" });
} else {
setAlert({ show: true, message: "Invalid credentials. Please try again.", variant: "danger" });
}
} catch (error) {
setAlert({ show: true, message: "An error occurred. Please try again later.", variant: "danger" });
}
};

Troubleshooting Process

The reason for this problem is the browser's same-origin policy limitation. By default, the browser only allows access to resources that are of the same origin (same protocol, domain name, and port) as the current page. In this case, the front-end runs on http://localhost:5173, while the back-end runs on http://localhost:5000. Since their ports are different, they belong to different origins. Without proper CORS policy configuration, the server does not explicitly allow requests from http://localhost:5173, so the browser blocks the front-end's cross-origin requests. Here is an example of incorrect code without proper CORS policy configuration:

// In the original code, only the response headers were simply set without using the CORS package
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE");
next();
});

Solutions

To solve the CORS policy problem, you can follow these steps:

  • Run the command npm i cors on the server side to install the CORS package.
  • Use CORS in server/App.js. Here is an example code:
// Import CORS
const cors = require("cors");
const app = express();
// CORS options, allowing requests from the front-end running on port 5173
const corsOptions = {
origin: "http://localhost:5173", // Only allow requests from this origin
methods: "GET,POST,PUT,DELETE", // Only allow these methods
allowedHeaders: ["Content-Type", "Authorization"], // Only allow these request headers
};
// Use the CORS middleware and specify the options
app.use(cors(corsOptions));

Summary and Reflection

In simple terms, this problem occurs because the front-end and the back-end run on different ports. For security reasons, the browser does not allow the front-end to directly access the back-end resources, which is the cross-origin problem. The solution is to install the cors package on the back-end and then configure it to tell the server that it can accept requests from the port where the front-end is located. In this way, the front-end can access the back-end resources normally. When developing projects with separate front-end and back-end, be sure to pay attention to the cross-origin problem and configure the CORS policy in advance to avoid such errors.