Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

模板引擎下的前后端通信 #3

Open
ZZR-china opened this issue Sep 6, 2017 · 0 comments
Open

模板引擎下的前后端通信 #3

ZZR-china opened this issue Sep 6, 2017 · 0 comments
Labels

Comments

@ZZR-china
Copy link
Owner

ZZR-china commented Sep 6, 2017

今天和后端搞了一下午的session跨域问题,苦思bug解决之法时回想起以前模板引擎的美好来,仅以此篇献给逝去的 ejs、handlebars、pug...

服务端使用模板引擎时,前后端同源,前端直接把页面样式写好甩给后端,后端根据使用的模板引擎,将数据套进去,没什么跨域问题。这时候session和cookie可以大显身手,用户的各种信息直接放在里面,长期保存的放cookie,短期的像什么登陆验证码之类的就放session。

之前做nodejs后端开发,公司用的是express+ejs,每次开发什么新功能都是前端妹子把页面写好,然后我来处理页面的数据交互等问题,有时候我还要帮她处理些js bug,想想当时还能跟妹子交流真是开心(现在的公司技术清一色的汉子)。记得当时有个全局的处理函数,是用来判断用户的登陆状态的,简单写下:

var express    = require('express'),
    router     = express.Router(),
    _buylimit  = require('../service/buylimit.service'),
    login_help = require('../helpers/login_help');

router.route('/buylimits')
  .get(function(req, res) {
    login_help(req, res, function() {
      _buylimit.getAll(function(buylimits) {
        res.render('buylimits', {buylimits: buylimits});
      });
    });
  })

这里的res.render就是express中的渲染函数,直接将buylimit这个数据集合放到ejs文件中。login_help嵌套在render之前用来判断session中是否有用户的登陆信息,有的话继续,没有的话重定向到login界面,login_help的代码如下:

var help = function(req, res, next) {
  var admin = req.session.admin;
  if(!admin) {
    res.redirect('/dashboard/login');
    return;
  } else {
    next();
  }
};

module.exports = help;

req.session这个方法可以直接获取session中数据。其实这里应该把login_help当作中间件,然后将判断的结果放到req中去的。express+ejs的确是很方便的组合,当时的技术老大使用这一组合只用了一个月就开发出了公司的产品框架,包含微信端和后台管理页面,将快速开发诠释到了极致。不过后期的各种报错就不谈了,程序员的报错不叫报错,叫八阿哥。

为了让观众更好的理解模板引擎下的前后端开发方式,下面简单实现一个express+ejs的登陆。首先上express后端代码。

var express       = require('express'),
    router        = express.Router(),
    admin_service = require('../service/admin.service'),
    login_help    = require('../helpers/login_help'),
    message       = require('../helpers/message');

router.route('/login')
  .get(function(req, res) {
    var admin = req.session.admin;
    if(admin) return res.redirect('/');
    res.render('login');
  })
  .post(function(req, res) {
    var user = {
      username: req.body.username,
      password: req.body.password
    },
    msg = new message();
    admin_service.login(user, function(bo, admin) {
      if(bo) {
        msg.msg           = '登录成功!';
        msg.status        = 1;
        req.session.admin = admin;
      } else {
        msg.msg = '登录失败!';
      }
      res.send(msg);
    });
  });

router.route('/logout')
  .get(function(req, res) {
    login_help(req, res, function(){
      req.session.admin = null;
      res.send(true);
    });
  });

module.exports = function(app) {
  app.use('/', router);
};

路由 get /login渲染了登陆页面,并做了事先的判断,post /login是登陆页面中的提交事件,判断username和userpassword是否正确,与数据库中的记录进行比对。再看前端页面:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />
    <title>后台登录 - Foowala</title>
</head>

<body>
    <input type="hidden" id="TenantId" name="TenantId" value="" />
    <div class="loginWraper">
        <div id="loginform" class="loginBox">
            <div class="form form-horizontal">
                <div class="row cl">
                    <label class="form-label col-xs-3"><i class="Hui-iconfont">&#xe60d;</i></label>
                    <div class="formControls col-xs-8">
                        <input id="username" name="username" type="text" placeholder="账户" class="input-text size-L radius">
                    </div>
                </div>
                <div class="row cl">
                    <label class="form-label col-xs-3"><i class="Hui-iconfont">&#xe60e;</i></label>
                    <div class="formControls col-xs-8">
                        <input id="password" name="password" type="password" placeholder="密码" class="input-text size-L radius">
                    </div>
                </div>
                <div class="row cl">
                    <div class="formControls col-xs-8 col-xs-offset-3">
                        <input id="login" name="login" type="submit" class="btn btn-primary radius size-L" value="&nbsp;登&nbsp;&nbsp;&nbsp;&nbsp;录&nbsp;">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="footer">Copyright Foowala by admin.v1.0</div>
    <script type="text/javascript">
      app.login();
    </script>
</body>

</html>

因为在同一域名下,不需要担心什么跨域问题,点击按钮时候直接ajax上传username和password,然后根据返回的参数进行处理即可。整个开发流程很顺畅,当然,这只是一个最简单的登陆模块的开发。管中窥豹,还是能看到这种模式的优点。

当时express没用了几天就换到了hapi框架上去,hapi用起来还是很爽的。当时使用hapi框架是为了开发的一个ipad端的应用,前端使用的是react-native,后端是nodejs hapi框架,算是第一次接触前后端分离,以一个后端的身份。

@ZZR-china ZZR-china changed the title 前后端分离下的cookie、session、localstorage 模板引擎下的前后端通信 Sep 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant