I am trying to connect my front end to my back end, and I am using express server with node and react.
this is my fetch request fom front end: server runs on port 5000
const response = await axios.post("http://localhost:8000/send-email", {
to_email: data.data.email,
url: data.data.url,
});
console.log(response);
this resutls in:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/send-email. (Reason: CORS request did not succeed). Status code: (null).
I have in my back end:
app.post("/send-email", async (req, res) => {
try {
const { to_email, url } = req.body;
console.log(to_email, url);
await sendMail()
.then((result) => console.log("Email sent...", result))
.catch((error) => console.log(error.message));
res.send({ express: "YOUR EXPRESS BACKEND IS CONNECTED TO REACT" });
} catch (error) {
console.log(error);
res.status(500).json({ message: error });
}
});
I am also using core and also something like this:
// app.use(function (req, res, next) {
// // res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Origin", "http://localhost:3000");
// res.header(
// "Access-Control-Allow-Headers",
// "Origin, X-Requested-With, Content-Type, Accept"
// );
// res.header("Access-Control-Allow-Methods", "POST, OPTIONS");
// res.header("Access-Control-Allow-Credentials", true);
// next();
// });
but regards less I keep getting this error and I am not sure how to get rid of it. I have seen several solutions they are either old, and I have tried some of them, they dont work at all.
CodePudding user response:
Install cors using (npm install cors)
in your backend code file
var cors = require('cors')
app.use(cors())
Or follow instructions here in this link https://www.npmjs.com/package/cors
CodePudding user response:
One way to do it is to use a proxy in your React app.
You can achive this by adding this line to your package.json file: "proxy": "http://localhost:8000" which is fine for development.
So your package.json looks something like this with create-react-app:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
// use correct port of your localhost API
// and pay attention that there is no slash behind the port
// if you use slash in your app like this: /api
"proxy": "http://localhost:8000",
In your react app, you can now POST to your endpoint /send-mail. As package.json was changed, app restart is needed
const response = await axios.post("/send-email", {
to_email: data.data.email,
url: data.data.url,
});
If this is not flexible enough, proxy can be added manually as well with package http-proxy-middleware. For this src/setupProxy.js needs to be created with following code, see also docs here of create-react-app
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
Full example with proxy in package.json
Frontend React
running on http://localhost:3000Send for demo purposes hard coded data to backend. My server runs on port 8000 so I use: "proxy": "http://localhost:8000" in my package.json:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:8000",
import axios from "axios";
const App = () => {
const postToBackend = async () => {
const res = await axios.post("/send-mail", {
to_email: "[email protected]",
url: "test-uri",
});
console.log(res.data);
};
return <button onClick={() => postToBackend()}>send to backend</button>;
};
export default App;
Backend Node.js
running on http://localhost:8000Read incoming data from react frontend and console.log the data. My folder structure:
├── app.js
└── routes
└── api
└── test.js
test.js Route This route will parse the request body, print it and returns it with status 200.
const express = require("express");
const router = express.Router();
router.post("/", async (req, res) => {
const { to_email, url } = req.body;
try {
// this will print the test-email and test-uri hard coded in frontend
console.log(to_email, url);
// return values with status 200
res
.status(200)
.json({ message: `Incoming data is ${to_email} and ${url}` });
} catch (error) {
res.status(400).json({ message: error.message });
}
});
module.exports = router;
app.js
In app.js just register the route, in my case I do it like this:
const express = require("express");
// express app
const app = express();
app.use(express.json());
// tell express to use /send-mail as endpoint for
// above route (stored in folder routes/api/test.js
app.use("/send-mail", require("./routes/api/test"));
// run server
const PORT = process.env.PORT || 8000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
Thats it, you should be able to send data from your frontend to your backend.
CodePudding user response:
Add proxy in your package.json file to the port of your backend api
"proxy": "http://localhost:8000"
then change your url in the request to port 3000 or wherever your frontend is
const response = await axios.post("http://localhost:3000/send-email", {
to_email: data.data.email,
url: data.data.url,
});
console.log(response);
proxy only works in local, however your app and api usually share the same main domain so this cors error will not appear in production..
