Node实践总结3——routes
来源:互联网 发布:知乎男士商务皮鞋 编辑:程序博客网 时间:2024/06/05 19:03
routes
一个传统的网站往往会有许多路径(/
,/login
,/user
),不同的路径对应不同的页面,有不同的处理逻辑,涉及表单的页面往往还会同时存在get
和post
两种形式的请求,其往往也承担了核心的业务。
routes结构
GET
先摘一段我工程的代码举个例子:
router.get('/', async function (ctx, next) { await ctx.render('index', { title: 'OA', user: ctx.session.user });});router.get('/reg', async function (ctx, next) { await ctx.render('reg', { title: 'OA-注册' });});router.get('/login', async function (ctx, next) { await ctx.render('login', { title: 'OA-登录' });});router.get('/logout', async function (ctx, next) { ctx.session.user = null; return ctx.redirect('/');});router.get('/user_app', async function (ctx, next) { await ctx.render('user_app', { title: 'OA-应用角色管理' });});router.get('/user_db', async function (ctx, next) { await ctx.render('user_db', { title: 'OA-数据库角色管理' });});router.get('/waf_log', async function (ctx, next) { var wafLogs = await WafLogs.fetchAll();//从数据库中查询所有的日志信息 var logs = {}; for(var i = 0;i < wafLogs.length;i++){ logs[i] = wafLogs.models[i].attributes; } await ctx.render('waf_log', { title: 'OA-waf日志', logs: logs });});
这一部分基本都是简单的get页面的请求,koa使用ctx.render(模板名,{模板需要的变量})
做页面渲染,第一个参数指定要使用哪一个模板文件作为返回的页面,第二个参数用于传入变量给jade模板使用。
GET请求时,通常需要服务器返回一个静态页面,所以逻辑都还算比较简单,只需要指定好页面模板和相应的变量即可。
上述例子中,有一个GET /waf_log
的route比较特别,这一个get请求需要服务器先查询存放日志的数据库,将日志信息保存成json格式,再由render函数传给模板进行渲染,下面将这一部分前后端的关键代码放在一起对比的看一下。
//后端router.get('/waf_log', async function (ctx, next) { var wafLogs = await WafLogs.fetchAll();//从数据库中查询所有的日志信息 var logs = {}; for(var i = 0;i < wafLogs.length;i++){ logs[i] = wafLogs.models[i].attributes; } await ctx.render('waf_log', { title: 'OA-waf日志', logs: logs });});
//前端doctype htmlhtml head meta(charset='utf-8') title= title link(rel='stylesheet' href='http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css') link(rel='stylesheet' href='/stylesheets/mycss.css') script(src='http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js') script(src='http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js')body div.container div.row ul.list-inline li.col-lg-3.nonpadding p.content-title WAF日志 li.col-lg-6.nonpadding li.float-right.col-lg-3.nonpadding div.input-group input#searchBox.form-control(type='text',placeholder='输入关键字,支持模糊查询',required) span.input-group-btn input.btn.btn-warning.btn-search(type='submit',value='搜索') div#table.row table.table thead tr th 序号(id) th 时间(time) th 用户名(username) th 访问的功能(function) th 访问的URL(url) th 参数(param) th 操作结果(result) tbody each log in logs tr each val in log td #{val}
可以看到后端传给模板两个参数{title: 'OA-waf日志',logs: logs}
,
模板中title= title
,说明前端页面中<title>
标签内容是一个变量,值是传入的title参数的值,
模板中tbody
下是两个each循环,用于将传入的logs解析出来,动态的生成表格。
async
和await
是ES7标准中用于处理异步操作的关键字,async
声明的函数A中可以使用await
调用别的函数B,并等到函数B返回之后继续执行A剩余的部分。
ctx
是koa2中包装req
和res
的对象。
next
用于链式操作,指代当前函数的下一个函数,常常通过await next()
调用。
POST
下面这一部分的routes相对复杂一些:
router.post('/reg', async function (ctx, next) { if(ctx.request.body['username'].length > 25) { //判断用户名是否过长,数据库设置username字段为varchar(25) await ctx.render('reg', { title: 'OA-注册', error: '用户名不得超过25个字符' }); } else if(ctx.request.body['password2'] !== ctx.request.body['password']) { //判断两次密码是否一致 console.log('两次密码不一致'); await ctx.render('reg', { title: 'OA-注册', error: '两次密码不一致' }); } else { //判断用户名是否存在 var count = await Users.where('username', ctx.request.body['username']).count('username'); if(count != 0) { console.log('用户名已存在!'); await ctx.render('reg', { title: 'OA-注册', error: '用户名已存在' }); } else { var hmac = crypto.createHmac('sha256', 'liuyueyi'); var password = hmac.update(ctx.request.body['password']).digest('hex'); console.log(password); console.log(password.length); var newUser = new Users({ username: ctx.request.body['username'], password: password }); await newUser.save(); console.log('注册成功,可以直接登录!'); ctx.session.user = newUser; await ctx.render('reg', { title: 'OA-注册', success: '注册成功,可以直接登录' }); return ctx.redirect('/login'); } }});router.post('/login', async function (ctx, next) { //需要判断的逻辑:用户名不存在或者密码错误 var count = await Users.where('username', ctx.request.body['username']).count('username'); if(count == 0) { console.log('用户名不存在!'); await ctx.render('login', { title: 'OA-登录', error: '用户名不存在' }); } else { var hmac = crypto.createHmac('sha256', 'liuyueyi'); var password = hmac.update(ctx.request.body['password']).digest('hex'); var user = await Users.where('username', ctx.request.body['username']).fetch(); if (user.attributes.password == password) { console.log('登陆成功!'+ user.attributes.username); ctx.session.user = user.attributes.username; return ctx.response.redirect('/'); } else { console.log('密码错误!'); await ctx.render('login', { title: 'OA-登录', error: '密码错误' }); } }});
这一部分是处理前端post回来的表单数据的逻辑代码。
render和redirect
上面的代码中,页面切换使用到了两种方法
- render
- redirect
二者是有区别的。
render用于页面渲染,是将指定的模板通过引擎转换成html之后直接画在当前页面之上,如果render指定的模板和当前页不同,地址栏上可以清晰的看见路径没有变化。
redirect则是用于页面跳转,服务器端的后台可以看到跳转的时候响应码是302,并且地址栏的路径也会变化。
AJAX
这一部分我之后单独写。
routes代码可以直接写在app.js当中,但是当业务越来越复杂,页面越来越多的时候,app.js会变得很长,从而不易维护,所以正确的做法是将其移到routes路径下,做成一个模块,使用的时候导入到app.js中。
- Node实践总结3——routes
- Node实践总结2——views
- Node实践总结5——AJAX
- Node实践总结1——快速开始
- Node实践总结4——数据库操作
- Node实践总结6——多表查询
- Node.js项目3文件(view,app,routes)关系
- Node.js的实践总结
- 不完全node实践教程-总结
- NodeJs——Express、Routes使用【二】
- Routes
- Ruby on Rails(ROR)——rake routes
- 【codeforces】601A—— The Two Routes
- 【UML实践】——实战总结
- Linux学习总结——实践
- FLEX实践—使用CSS的总结
- AngularJS—AngularJs项目实践总结
- Node.js实践
- 040队列
- AngularJS实例——选项卡
- Linux下添加shell脚本使得nginx日志每天定时切割压缩
- ssh框架中关于泛型<T>的·使用
- 050树
- Node实践总结3——routes
- 060查找
- C/C++ OpenCV图像的尺寸变化
- 查看并修改Linux主机名命令hostname
- httpClient
- 007排序
- Android Stduio环境配置
- 关于Android Studio中的org.gradle.jvmargs=-Xmx1024m问题
- liux 重定向