最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin3浏览0评论

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.

发布评论

评论列表(0)

  1. 暂无评论