0

I have a login form which is collect user email and password. Then I use JavaScript fetch to post data to express. then I use express validator check the inputs are correct. Then I send response res.status(200).redirect("/auth"); like this, but JavaScript is prevent the login page to redirect because in my external JavaScript I use e.preventDefault() function. But I want to redirect to next page. When I remove e.preventDefault() it stops the validation so I cant remove that. What should I do?

I'm using Node, Express Js, JSON file for storing Data, EJS Template with external JavaScript file. Aslo serving static JavaScript file too which is located in public/js/script.js file. Also using express-validator in middleware folder to validate the fields

Here is the express code:

export const loginsHandle = async (req, res) => {
  const {
    email,
    password,
  } = req.body;

  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(422).json({
      errors: errors.array(),
    });
  } else {
    try {
      var accountPP = new PP({
        email: email,
        password: password,
      });
      let addingData = JSON.parse(fs.readFileSync(accountDataFile, "utf-8"));
      addingData.push(accountPP);
      await fs.writeFileSync(accountDataFile, JSON.stringify(addingData));
      res.status(200).redirect("/auth");
    } catch (error) {
      console.log(error);
      res.status(200).send(error);
    }
  }
};

Here is external JavaScript :

const form = document.querySelector("form");
const emailInput = document.getElementById("email");
const passwordInput = document.getElementById("password");
const btn = document.getElementById("submit");
const forGot = document.getElementById("forgot");
const singBtn = document.getElementById("sign");
const footer = document.getElementById("menuFoot");


forGot.addEventListener("click", (e) => {
  e.preventDefault();
});
singBtn.addEventListener("click", (e) => {
  e.preventDefault();
});
footer.addEventListener("click", (e) => {
  e.preventDefault();
});


form.onsubmit = sendLogin;

function sendLogin(e) {
  e.preventDefault();
  let formData = new FormData(form);
  let Params = {
    headers: {
      "Content-Type": "application/json",
      accept: "application/json",
    },
    body: JSON.stringify({
      email: formData.get("email"),
      password: formData.get("password"),
    }),
    method: "POST",
  };
  fetch("http://localhost:5001/login", Params)
    .then((res) => {
      return res.json();
    })
    .then((data) => {
      if (data.errors) {
        data.errors.forEach((err) => {
          if (data.errors[0].param == "email") {
            emailInput.style.borderColor = "red";
          } else if (data.errors[0].param == "password") {
            passwordInput.style.borderColor = "red";
          } else {
            emailInput.style.borderColor = "";
            passwordInput.style.borderColor = "";
          }
        });
      }

      return data;
    })
    .catch((error) => console.log(error, "error"));
}
Kaneki21
  • 1,323
  • 2
  • 4
  • 22
Change
  • 19
  • 8
  • can you share the backend code for `/auth` as well. also can you do some `console.log` in the `/auth` handler..to check if it's hit or not – Kaneki21 Sep 24 '22 at 01:51
  • Auth is just simple EJS page with success message in it. I just want to redirect to any other page. Yah when I console log in auth route it show the log in terminal. but browser shows same login page – Change Sep 24 '22 at 01:59
  • If `/auth` has `res.render` then that should have also changed the page. That did not work? – Kaneki21 Sep 24 '22 at 02:20
  • Yes it has res.render but when I click submit does nothing – Change Sep 24 '22 at 02:58
  • `redirect` should have worked...I'm suspecting the `then` is causing the error in the `fetch` call as you are also trying to check error there. But another option would be that you use `login` for just credential check and then based on `success` or `failure` you display message(in case of error) or rediect to `success` page – Kaneki21 Sep 24 '22 at 03:10
  • How to do this bro? Any reference please – Change Sep 24 '22 at 03:38
  • can you give [this](https://www.geeksforgeeks.org/how-to-redirect-to-generated-url-with-expressjs/) a try – Kaneki21 Sep 24 '22 at 04:11

1 Answers1

2

When you send a REST request using fetch() in the browser, the browser doesn't process the response. It's up to your code to look at the status code and body of the response and take any action that you need to. The browser will not change the URL based on the response.

My recommendation is to use 200 to indicate that the login was successful, and then in the browser code, navigate to /auth. In your server code, you should send a 500 status instead when there's an error.

To simulate a redirect, your best bet is to use location.replace (see How do I redirect to another webpage? for a discussion on why):

window.location.replace('/auth.html')
asselin
  • 1,831
  • 2
  • 13
  • 18
  • Can you please share me a sample code for redirect to next page with JavaScript? – Change Sep 24 '22 at 02:01
  • Sure thing, see edited answer above. If this is helpful, would you mind clicking to accept it as the answer? – asselin Sep 24 '22 at 02:16
  • I add some validation in the form but window.location.replace("/auth") is skip those validation. When place this line with in function is not working and receiving JSON data error – Change Sep 24 '22 at 03:02
  • Place it inside the `.then()` after you get a response from the server: fetch("http://localhost:5001/login", Params) .then((data) => { if (!data.errors) { window.location.replace('/auth.html') } }) – asselin Sep 24 '22 at 03:23
  • SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data error . Got this error bro. – Change Sep 24 '22 at 03:37
  • The JSON parse error is probably because you're not sending back a body on the response of the 200. You could replace res.status(200).redirect("/auth") with res.status(200).send({}) so that it's sending back valid JSON. – asselin Sep 24 '22 at 13:11
  • ok bro res.send will render or redirect new page? – Change Sep 24 '22 at 13:30
  • The res.send() just sends an empty response back to the browser. The idea is that the code in the browser sees the 200 response, then calls window.location.replace() and THAT call is what does the redirect. – asselin Sep 24 '22 at 13:33
  • Very helpful informations – Change Sep 24 '22 at 14:02