1.路由处理
我们通过访问 http://localhost:1234/已经显示了默认首页内容。
我们打开app.js文件,看路由处理部分代码:
我们知道请求方式有get和post,我们当前的方式是get请求,并且请求项目路径是 “/”
在程序中我们可以看到,当地址是“/”时,会调用routers.index的处理,这是文件模块的定义
我们打开routes目录下的文件模块,查看代码程序:
我们此时会比较疑惑,通过require加载的模块代码是这样的:
var routes = require('./routes');
其实这个方法会自动去找下面的index.js文件,我们改写成这样同样可以,为了理解方便
var routes = require('./routes/index');
后缀名可缺省,大部分的模块都是js文件,会自动识别。
修改后,我们可以ctrl+c结束,然后npm start重新启动,地址刷新发现是没有问题的。
这里我们知道,我们写的文件模块会挂在 exports或者module.exports对象下,就可以通过require()获取到。
现在我们已经知道,访问根目录“/”,会调用index.js的index方法,我们看到方法里面的处理程序是:
res.render('index', { title: 'Express' });
req和res对象不多说,利用http模块创建服务器已经非常熟悉,在这里express对两个对象做了更多的包装,
打开express的api手册,我们查看说明:http://www.expressjs.com.cn/4x/api.html#res.render
在手册我们可以看到,res的render方法有三个参数,
arg1:使用的模板引擎名称(就是调用那个引擎页面,我们的ejs)
arg2:就是传入引擎的内容({}类型),
arg3:错误时执行的回调
看到这里我们几乎就明白了,我们访问“/”会使用index的模板页面,并且穿入模板的内容:键是title值是express,我们把
res.render('index', { title: 'Express' });
修改为:
res.render('index', { title: 'Express',hello:'hello world!' });
既然这里会模板index传入数据,那么模板index肯定要接收和处理数据,我们打开index模板页面:
现在是title的显示,我们修改index.ejs代码,加入hello的显示,与路由处理同步
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <p><%= hello %></p> </body> </html>
重启运行,刷新浏览器,会看到传入的新数据:
我们一个网站肯定会有多个网页,之间进行跳转操作,当然这就是路由的功能了,我们现在访问的根路径是“/”,此时我们需要多一些页面来了解路由的工作处理。
我们修改index.ejs页面,加入一些a标签做跳转演示
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <p><a href="/hello"><%= hello %></a></p> </body> </html>
此时我们点击“hello world”会跳转到“/hello”页面,好了我们此时要加入对“/hello”的路由处理了
app.js加入理由处理:
index.js加入处理程序:
/* GET home page. */ exports.index = function(req, res){ res.render('index', { title: 'Express',hello: 'hello world!' }); }; /* GET hello page. */ exports.hello = function(req, res){ res.render('hello', { text: '么么哒' }); };
我们会往hello.ejs模板页面传入“么么哒”,我们创建hello.ejs,写入代码:
通过index.ejs复制修改即可,从路由,到处理,到模板全部书写完毕,我们重启后,刷新页面,点击测试!
似乎没有问题了,不过我们页面会有大量的路由处理,如果我们全部放在app.js,会发现如入口文件越来越大,越来越混杂,我们最好是把路由的处理分离处理,单独在一个模块去处理,
其实路由的处理,就是调用app对象,我们只要把app对象作为参数传入到外面,似乎就实现分离了,我们对index.js做修改,把app对象传入到index.js页面
修改后我们的所有路由处理就全部在index.js进行了,index.js代码:
function rout(app){ app.get('/',function(req, res){ res.render('index', { title: 'Express',hello: 'hello world!' }); }); app.get('/hello', function(req, res){ res.render('hello', { text: '么么哒' }); }); }; exports.rout=rout;
我们要在app.js调用index的程序和传入app对象,app.js修改如下:
重启,运行,如果报错要自己查看是否书写错误。
2.ejs模板引擎的了解和处理
我们上面其实已经使用和简单了解的ejs的使用,我们为什么可以使用ejs,不要深究,我们知道在哪里引入就可以了,
我们在app.js可以看到下面的代码:
__dirname是node的全局变量,会获取到当前文件的目录,不要深入理解了,知道就好!
我们对比路由页面和模板页面程序:
这非常清晰了吧,res.render发出的数据会被模板介绍和显示,中间的桥就是那个键名,并且ejs是在<% %>放程序代码的,
里面的“=”其实就等同于php的echo。
其实现在我们发送的都是单一数据,可以说是1,其实很多时候是n,当时就是数组的形式了,我们修改index.js的根路由控制
我们要利用ejs来显示数组形式的数据了,修改index.ejs的代码:http://www.embeddedjs.com/
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <p><a href="/hello"><%= hello %></a></p> <ul> <% for(var i=0; i<arr.length; i++) {%> <li><%= arr[i] %></li> <% } %> </ul> </body> </html>
其实语法和js没太大区别,我们看看就知道了,
重启运行,刷新页面查看:
当然还有if的处理等,我们遇到在查看手册就可以!
3.get/post参数获取和路径跳转
=====首先是get的参数获取,我们看手册地址:
获取get参数有2中方法,其实利用req.query获取的感觉更加常见,我们知道参数的地址一般如下:
localhost:80/peo?a="123"&b="999"
然后我们获取a和b的参数值就可以了,不过express还提供了后面做路径的处理方法,也就是req.params,
localhost:80/peo/123 把123作为参数值,这个其实针对只有一个参数的是很方便的,多个参数我们还是要利用req.query
其实用什么还是看你的设计和处理,适合就行。
针对get请求,?的形式就不用过多解释,我们分析把路径做参数的处理方式
把路径作为参数内容,在路由处理时,要用:xx的形式,xx可以使用req.params.xx获取到参数值。
我们修改index.ejs代码,测试路径做参数的处理操作:
我们鼠标hover在列表链接上会看到地址如下:
localhost:1234/list/0
localhost:1234/list/1
localhost:1234/list/2 ......
我们既然把路径做参数,那么0-x就是参数值了,我么要在路由进行获取和处理:
我们加入处理,修改index.js:
我们创建list.ejs,显示内容:
<!DOCTYPE html> <html> <head> <title>list</title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= text %></h1> </body> </html>
重启,运行,我们点击列表,会发现点击进入的页面会把路径做参数获取和显示在页面内部:
其实这样处理的方式比较少见,参数大部分都是以?key1=val1&key2=val2的形式
我们修改index.ejs代码,改为常见形式:
我们的路由处理,进行修改:
我们发现和使用上面的方法结果是一样的,这样看起来更常见。
=====下面我们处理post请求参数
其实post和get区别不是很大,不过一般使用post处理的数据都是隐性的,我们就用登录做处理演示:
1.有一个登录界面,
1.我们创建login.ejs
2.路由加入 get的/login处理,指向login.ejs
3.登录时 做post处理,我们加入post的logincheck路由处理
4.logincheck路由会获取参数,成功会跳到根目录,失败跳到login目录
开始书写程序:
login.ejs代码如下:
<!DOCTYPE html> <html> <head> <title>login</title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <form method="post" action="/logincheck"> <input type="text" placeholder="用户名" name="user"> <input type="password" placeholder="密码" name="pass"> <input id="ok" type="submit" value="登录"> </form> </body> </html>
路由文件index.js加入处理:
重启,运行,地址敲入:http://localhost:1234/login
我们就会看到登录界面了:
我们点击登录,看看有何变化,会提示404,我们没有对/logincheck做路由处理,我们在index.js加入处理,post操作
此时问题出现了,怎么获取参数,这个比较简单,然后怎么跳转?
req.body.user和req.body.pass就获取到了用户名和密码。
我们可以写一个死判断就是用户名等于“tom”和密码等于"tom"算登录成功,成功跳转,其他失败!
路由修改:
app.post('/logincheck', function(req, res){ var user= req.body.user; var pass= req.body.pass; if(user=="tom" && pass=="tom"){ }else{ }; });
里面在写跳转就可以了,就和php的header方法一样,
我们在手册查看跳转方法:
我们修改路由处理如下:
app.post('/logincheck', function(req, res){ var user= req.body.user; var pass= req.body.pass; if(user=="tom" && pass=="tom"){ res.redirect('/'); }else{ res.redirect('/login'); }; });
重启,运行,如果用户名和密码都是tom就会跳转到首页面了。
4.总结
到这里,我们的基本处理都结束了,添加和修改了很多文件,我在下面把源码粘贴出来!
app.js:修改比较少,主要是把app对象传出
var express = require('express'); var http = require('http'); var path = require('path'); var favicon = require('static-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); var users = require('./routes/user'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(favicon()); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use(app.router); routes.rout(app); app.get('/users', users.list); /// catch 404 and forwarding to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); /// error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.render('error', { message: err.message, error: {} }); }); module.exports = app;
index.js:修改较多,多个路由分析
function rout(app){ app.get('/',function(req, res){ res.render('index', { title: 'Express',hello: 'hello world!',arr:[111111,2222,33333,44444] }); }); app.get('/hello', function(req, res){ res.render('hello', { text: '么么哒' }); }); app.get('/list', function(req, res){ res.render('list', { text: req.query.id }); }); app.get('/login', function(req, res){ res.render('login'); }); app.post('/logincheck', function(req, res){ var user= req.body.user; var pass= req.body.pass; if(user=="tom" && pass=="tom"){ res.redirect('/'); }else{ res.redirect('/login'); }; }); }; exports.rout=rout;
index.ejs
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <p><a href="/hello"><%= hello %></a></p> <ul> <% for(var i=0; i<arr.length; i++) {%> <li><a href="/list?id=<%= i %>"><%= arr[i] %></a></li> <% } %> </ul> </body> </html>
list.ejs
<!DOCTYPE html> <html> <head> <title><%= title %></title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= title %></h1> <p>Welcome to <%= title %></p> <p><a href="/hello"><%= hello %></a></p> <ul> <% for(var i=0; i<arr.length; i++) {%> <li><a href="/list?id=<%= i %>"><%= arr[i] %></a></li> <% } %> </ul> </body> </html>
hello.ejs
<!DOCTYPE html> <html> <head> <title>hello</title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1><%= text %></h1> </body> </html>
login.ejs
<!DOCTYPE html> <html> <head> <title>login</title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <form method="post" action="/logincheck"> <input type="text" placeholder="用户名" name="user"> <input type="password" placeholder="密码" name="pass"> <input id="ok" type="submit" value="登录"> </form> </body> </html>
www目录下端口为1234