Home > Net >  react app express server CORS request did not succeed
react app express server CORS request did not succeed

Time:01-09

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:

  1. Install cors using (npm install cors)

  2. 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:3000

Send 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:8000

Read 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..

  •  Tags:  
  • Related