-1

I have worked with Cors before in a MEAN stack app. And it perfectly played its role. However, now I am transitioning to the MERN stack, I keep getting this error despite using CORS in the backend:

Access to XMLHttpRequest at 'http://localhost:5000/api/users/register' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Register.js:43 Error: Network Error
    at createError (createError.js:16)
    at XMLHttpRequest.handleError (xhr.js:83)
xhr.js:178 POST http://localhost:5000/api/users/register net::ERR_FAILED  

So for some reason, CORS isn't doing what it's supposed to do?
Here's the main code:

Backend/server.js

// Use routes
app.use("/api/users", users);
app.use("/api/profile", profile);
app.use("/api/posts", posts);

// Use Cors
app.use(Cors());

//process.env.Port is for Heroku
const port = process.env.Port || 5000;
// `` ES6 Template literal is used so that we can put a variable inside the String
app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

Backend/routes/api/users.js

// @route  POST api/users/register
// @desc   Register user
// @access Public
router.post("/register", (req, res) => {
  // Before we do anything, we will validate the data
  const { errors, isValid } = validateRegisterInput(req.body);
  // Check validation
  if (!isValid) {
    return res.status(400).json(errors);
  }

  // First, we will use mongoose to find if the email exists
  // Because we don't want someone to register with an email that's already in the db
  // req.body.email is possible thanks to bodyParser module
  User.findOne({ email: req.body.email }).then(user => {
    if (user) {
      errors.email = "email already exists";
      return res.status(400).json({
        errors
      });
    } else {
      const avatar = gravatar.url(req.body.email, {
        s: "200", //Size
        r: "pg", //Rating
        d: "mm" //Default
      });
      // new Modelname({data})
      const newUser = new User({
        name: req.body.name,
        email: req.body.email,
        // This will be the avatar URL
        //avatar: avatar,
        // Since they are the same with ES6 we can do just avatar
        // But it doesn't know what avatar is, for this we will use gravatar
        avatar,
        password: req.body.password
      });
      bcrypt.genSalt(10, (err, salt) => {
        // If there's an error it'll give us an error, if not it'll give us a hash
        // A hash is what you want to store in the database
        bcrypt.hash(newUser.password, salt, (error, hash) => {
          if (error) {
            throw error;
          }
          newUser.password = hash;
          newUser
            .save()
            .then(user => res.json(user))
            .catch(err => {
              console.log(err);
            });
        });
      });
    }
  });
});

Frontend/src/components/auth/Register.js

    axios
  .post("http://localhost:5000/api/users/register", newUser)
  .then(res => {
    console.log(res.data);
  })
  .catch(err => console.log(err));
AG_HIHI
  • 1,705
  • 5
  • 27
  • 69

2 Answers2

3

You have to use cors before using the routes. If you don't do this and since your route handlers don't call next(), cors never has a chance to manipulate your response.

// Use Cors
app.use(Cors());

// Use routes
app.use("/api/users", users);
app.use("/api/profile", profile);
app.use("/api/posts", posts);

Ayush Gupta
  • 8,716
  • 8
  • 59
  • 92
  • That removed the error. But, I got another error xhr.js:178 POST http://localhost:5000/api/users/register 400 (Bad Request). I will google it but if you happen to know the solution already, let me know – AG_HIHI Feb 08 '20 at 11:46
  • 1
    That is a logical issuehappening in your code, specifically the line `return res.status(400).json(errors);` or due to invalid JSON input to your API. – Ayush Gupta Feb 08 '20 at 11:47
  • 4
    @AhmedGhrib You're deliberately sending back status 400, what did you expect? :) –  Feb 08 '20 at 11:48
  • @ChrisG I thought it was something unrelated with the code because in my code, I am actually sending along the errors which do not show up in the reponse. – AG_HIHI Feb 08 '20 at 11:50
0

Open it in dev mode:

app.use(
  cors({
    origin: (origin, callback) => callback(null, true),
    credentials: true
  })
);
Vahid Alimohamadi
  • 4,900
  • 2
  • 22
  • 37