最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Sending data to a modal without redirecting in nodejs - Stack Overflow

matteradmin4PV0评论

I am using passport and flash to manage authentication. I want to send flash messages back to the UI per the documentation. In my scenario in the UI I am using a modal so doing a

res.render('login.ejs', { message: req.flash('loginMessage') });

won't work because you can only render on a page refresh. Therefore how can I send flash dataor any other kind of data to my page when fails to log in for some reason. Regardless of flash data in particular I cannot figure out how to render data to a modal with express.

routes.js

below the res.render never happens on a authentication failure.

  //Home Page ===================================
  app.get('/', function(req, res) {
    res.render('login.ejs', { message: req.flash('loginMessage') });
  });

  //Login Modal =================================
  app.post('/login', passport.authenticate('local-login', {
    successRedirect : '/profile',
    failureFlash : true
  }));

index.ejs (where my modal is)

<div id="openModal" class="modalDialog">
  <div>
    <a href="#close" title="Close" class="close">X</a>
    <h2 id="logintitle">Log In</h2>

    <% if (message.length>0) { %>
      <div class="alert alert-danger">
        <%= message %>
      </div>
      <% } %>

        <form class="form-horizontal" action="/login" method="post" id="loginform">
          <div class="form-group inner-addon left-addon">
            <label class="sr-only" for="login_email">Email</label>
            <i class="glyphicon glyphicon-user"></i>
            <input type="email" class="form-control" name="email" placeholder="Email Address" />
          </div>
          <div class="form-group inner-addon left-addon">
            <label class="sr-only" for="login_pass">Password</label>
            <i class="glyphicon glyphicon-star-empty"></i>
            <input type="password" class="form-control" name="password" placeholder="Password" />
          </div>
          <div id="forgotpass">
            <a href="#openModal3" id="forgotpass">Forgot Password?</a>

          </div>
          <div class="form-group">
            <button type="submit" class="btn form-login-button">Log In</button>
          </div>
        </form>
        <div class="strike">
          <span>Log in with</span>
        </div>

        <div id="test" class="test">

          <a href="/auth/facebook" class="btn btn-primary"><span class="fa fa-facebook"></span> Facebook</a>
          <a href="/auth/google" class="btn btn-danger"><span class="fa fa-google-plus"></span> Google</a>

        </div>
  </div>
</div>

I am using passport and flash to manage authentication. I want to send flash messages back to the UI per the documentation. In my scenario in the UI I am using a modal so doing a

res.render('login.ejs', { message: req.flash('loginMessage') });

won't work because you can only render on a page refresh. Therefore how can I send flash dataor any other kind of data to my page when fails to log in for some reason. Regardless of flash data in particular I cannot figure out how to render data to a modal with express.

routes.js

below the res.render never happens on a authentication failure.

  //Home Page ===================================
  app.get('/', function(req, res) {
    res.render('login.ejs', { message: req.flash('loginMessage') });
  });

  //Login Modal =================================
  app.post('/login', passport.authenticate('local-login', {
    successRedirect : '/profile',
    failureFlash : true
  }));

index.ejs (where my modal is)

<div id="openModal" class="modalDialog">
  <div>
    <a href="#close" title="Close" class="close">X</a>
    <h2 id="logintitle">Log In</h2>

    <% if (message.length>0) { %>
      <div class="alert alert-danger">
        <%= message %>
      </div>
      <% } %>

        <form class="form-horizontal" action="/login" method="post" id="loginform">
          <div class="form-group inner-addon left-addon">
            <label class="sr-only" for="login_email">Email</label>
            <i class="glyphicon glyphicon-user"></i>
            <input type="email" class="form-control" name="email" placeholder="Email Address" />
          </div>
          <div class="form-group inner-addon left-addon">
            <label class="sr-only" for="login_pass">Password</label>
            <i class="glyphicon glyphicon-star-empty"></i>
            <input type="password" class="form-control" name="password" placeholder="Password" />
          </div>
          <div id="forgotpass">
            <a href="#openModal3" id="forgotpass">Forgot Password?</a>

          </div>
          <div class="form-group">
            <button type="submit" class="btn form-login-button">Log In</button>
          </div>
        </form>
        <div class="strike">
          <span>Log in with</span>
        </div>

        <div id="test" class="test">

          <a href="/auth/facebook" class="btn btn-primary"><span class="fa fa-facebook"></span> Facebook</a>
          <a href="/auth/google" class="btn btn-danger"><span class="fa fa-google-plus"></span> Google</a>

        </div>
  </div>
</div>

My understanding is I need to use javascript/ajax to prevent the post for being the redirect but I cannot figure out how to get the flash data to this point:

index.ejs (javascript)

$(function () {
        $("#loginform").on("submit", function(e) {
            e.preventDefault();
            $.ajax({
                url: $(this).attr("action"),
                type: 'POST',
                data: $(this).serialize(),
                beforeSend: function () {
                },
                success: function (data) {
                }
            });
        });
    });

EDIT added some code from passport.js

function passport_login(req, email, password, done) {
    //doing some validate and found bad password
    return done(null, false, req.flash('loginMessage', 'Invalid Password'));
})
Share Improve this question edited Apr 3, 2016 at 19:10 Weston asked Apr 3, 2016 at 2:55 WestonWeston 1431 silver badge8 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 3

So after quite a bit of digging I have found the solution. The key was in recognizing jquery not express is the answer, letting the client handle the redirects and posts/gets. I have only include updates for a local login strategy but they would apply for your signup/social other social profiles as well.

Changes to passport.js (minor)

function passport_login(req, email, password, done) {
    //doing some validate and found bad password
    return done(null, false, 'Bad Password');
})

Changes to my route (the part I struggled with)

The key things to note here is I am deciding what data I sent through res.send. I could send anything, in this case info is what es from passport.js ('Bad Password'). If i am happy and able to log in I send a simple little valid:true json.

  //Login Modal =================================
  app.get('/localLogin', function(req, res, next) {
    passport.authenticate('local-login', function(err, user, info) {
      if (err) { return next(err); }
      //if there is no user in the response send the info back to modal
      if (!user) {
        return res.send(info);
      }
      //user was able to login, send true and redirect
      req.logIn(user, function(err) {
        if (err) { return next(err); }
        return res.send({ valid: true });
      });
    })(req, res, next);
  });

Changes to my index.js

Added a div on top the my modal to display messages, remove old <%= message > piece and delete the action and method from the form jQuery will do that for us. (included full modal code to be transparent)

<div id="openModal" class="modalDialog">
  <div>
    <a href="#close" title="Close" class="close">X</a>
    <h2 id="logintitle">Log In</h2>
    <div id="loginPopup"></div>
    <form class="form-horizontal" id="loginform">
      <div class="form-group inner-addon left-addon">
        <label class="sr-only" for="login_email">Email</label>
        <i class="glyphicon glyphicon-user"></i>
        <input type="email" class="form-control" name="email" placeholder="Email Address" />
      </div>
      <div class="form-group inner-addon left-addon">
        <label class="sr-only" for="login_pass">Password</label>
        <i class="glyphicon glyphicon-star-empty"></i>
        <input type="password" class="form-control" name="password" placeholder="Password" />
      </div>
      <div id="forgotpass">
        <a href="#openModal3" id="forgotpass">Forgot Password?</a>

      </div>
      <div class="form-group">
        <button type="submit" class="btn form-login-button">Log In</button>
      </div>
    </form>
    <div class="strike">
      <span>Log in with</span>
    </div>

    <div id="test" class="test">

      <a href="/auth/facebook" class="btn btn-primary"><span class="fa fa-facebook"></span> Facebook</a>
      <a href="/auth/google" class="btn btn-danger"><span class="fa fa-google-plus"></span> Google</a>

    </div>
  </div>
</div>

Then I added the following Jquery code the last piece to the puzzle:

    $(function(){
        $('#loginform').on('submit', function(e) {
            e.preventDefault();
            var data =  $(this).serialize();
            $.get('/localLogin', data, function(result) {
                if(result.valid == true)
                {
                    window.location.href = '/profile';
                }
                else
                {
                    $('#loginPopup').html(result);
                }
            });
        });
    });

Hope this helps someone, the information for a full end to end solution on how to do this is sparse.

Post a comment

comment list (0)

  1. No comments so far