Node.js Express框架
一、Express 介绍
Express是一个最小的,灵活的Node.js Web应用程序框架,它提供了一套强大的功能来开发Web和移动应用程序。 它有助于基于Node Web应用程序的快速开发。Express框架的核心功能是:
- 允许设立中间件响应HTTP请求
- 定义了用于执行基于HTTP方法和URL不同动作的路由表
- 允许动态渲染基于参数传递给模板HTML页面
二、安装Express
安装Express 框架全局使用NPM,以便它可以被用来使用Node终端创建Web应用程序。
$ npm install -g express-generator
上面的命令在本地node_modules目录保存安装,并创建一个目录express在node_modules里边。还有,应该使用express安装以下几个重要的模块:
- body-parser :这是一个Node.js中间件处理JSON,Raw,文本和URL编码的表单数据
- multer :这是一个Node.js的中间件处理multipart/form-data
- cookie-parser : 解析Cookie头和填充req.cookies通过cookie名字键控对象
$ npm install body-parser --save
$ npm install cookie-parser --save
$ npm install multer --save
三、Express创建项目
一个非常基本的Express应用程序,它会启动服务器,并侦听端口3000等待连接。这个应用程序使用"Hello World! "回应!为请求网页。 对于所有其他路径,这将响应一个404表示未找到。
1、进入工作目录(自定义)
2、执行创建命令,创建一个名为hello的Express项目
express hello
表示安装成功
3、进入hello目录安装依赖包:
F:\hello> npm install
4、安装完成后,执行命令启动应用:
F:\hello>npm start
5、在浏览器中输入http://localhost:3000/
四、Express项目结构分析
1、bin:启动配置文件,在www 里修改运行端口号
2、node_modules:存放所有的项目依赖库,就像java存放架包
3、public:用于存放静态资源文件 图片,CSS,JAVASCRIPT文件..
4、routers:路由文件相当于springmvc中的Controller,ssh中的action
5、views:存放页面的地方
6、package.json:项目依赖配置及开发者信息。
7、app.js:应用核心配置文件,项目入口
五、app.js配置详解
app.js文件相当于项目启动的主入口文件,包含以下公共方法和服务器配置信息等
var createError = require('http-errors');//http错误处理模块
var express = require('express');//引入Express
var path = require('path');//引入path
var cookieParser = require('cookie-parser');//引入cookie处理对象
var logger = require('morgan');//引入日志模块
//引入路由目录中的index.js文件
var indexRouter = require('./routes/index');
//引入路由目录中的users.js文件
var usersRouter = require('./routes/users');
var app = express(); //创建express应用
// view engine setup
app.set('views', path.join(__dirname, 'views')); //定义页面目录
app.set('view engine', 'jade');//定义页面模板引擎
app.use(logger('dev'));//定义日志打印级别
app.use(express.json());//定义json格式处理数据
//定义使用urlencode处理数据及querystring模块解析数据
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());//定义使用cookie处理对象
app.use(express.static(path.join(__dirname, 'public')));//定义静态资源目录public
app.use('/', indexRouter);//定义指向index.js的路由
app.use('/users', usersRouter);//定义指向users.js的路由
// 定义404错误处理
app.use(function(req, res, next) {
next(createError(404));
});
// 定义其他错误处理
app.use(function(err, req, res, next) {
// 设置 locals, 只在开发环境生效
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// 返回错误http状态码
res.status(err.status || 500);
res.render('error');//渲染错误页面
});
module.exports = app; //导出app
一个页面的运行过程和逻辑大致分为三步,路由中间件(index.js)的书写同时中间件的模板(index.ejs)要写好、最后由app.js配置和调用路由中间件。
1、app.js配置
2、routes 调用路由级中间件
3、views 模板渲染
六、Express路由:
路由用于确定应用程序如何响应对特定端点的客户机请求,包含一个 URI(或路径)和一个特定的 HTTP 请求方法(GET、POST 等)。
每个路由可以具有一个或多个处理程序函数,这些函数在路由匹配时执行。它的使用形式如下:
app.method(path, handler)
app:是 express 的实例。
method:是 HTTP 请求方法。
path:是服务器上的路径。
handler:是在路由匹配时执行的函数。
注意:如果有多个路由处理程序,那么不是最后一个路由的情况下,其参数要有next:
next() 函数不是 Node.js 或 Express API 的一部分,而是传递给中间件函数的第三自变量。next() 函数可以命名为任何名称,但是按约定,始终命名为“next”。为了避免混淆,请始终使用此约定。
next函数主要负责将控制权交给下一个中间件,如果当前中间件没有终结请求,并且next没有被调用,那么请求将被挂起,后边定义的中间件将得不到被执行的机会。
七、Express的页面
1、更换模板引擎
Express默认的模板引擎是jade,为了方便用户开发,可以把它替换成更简洁、更高效的art-template
(1)安装art-template依赖包
npm install -S art-template
npm install -S express-art-template
(2)修改app.js文件
app.engine(‘.html’,requare(‘express-art-template’)
app.set(‘view engine’,’html’)
2、渲染数据到页面
在开发网页的时候,网页上的内容往往不是一成不变的,而是根据服务端内容变换的,这就需要将数据渲染到页面上。即调用response的render方法向页面传递数据,在页面中使用{{ 变量名 }}接收服务端的数据
router.get('/post',function(req,res){
res.render('post',{
title:'孔子学院',
name:'张三',
age:31,
happy:true
})
})
前端页面:
<p>
姓名:{{name}}
<br><br>
年龄:{{age}}
</p>
(1)条件渲染:根据不同的情况展示不同的页面
<h2>{{title}}</h2>
<!-- 判断年龄小于30-->
{{ if age<30 }}
<p>大家好,我是{{name}},我今年{{age}}岁,很高兴认识大家!</p>
{{ /if }}
<!-- 判断年龄大于等于30 -->
{{ if age>30 }}
<p>大家好,我是{{name}},很高兴认识大家!</p>
{{ /if }}
(2)嵌套条件渲染
<h2>{{title}}</h2>
<!-- 判断年龄小于30-->
{{ if age<30 }}
<p>大家好,我是{{name}},我今年{{age}}岁,很高兴认识大家!</p>
{{ /if }}
<!-- 判断年龄大于等于30 -->
{{ if age>30 }}
<p>大家好,我是{{name}}
<!-- 判断happy字段是否为真-->
{{ if happy }}
<span>很高兴认识大家!</span>
{{ /if }}
</p>
{{ /if }}
(3)循环渲染:
router.get('/post',function(req,res){
res.render('post',{
title:'德云IT学院',
list:[{
id:1,
content:'今天天气不错'
},{
id:2,
content:'昨天几点睡觉的?'
},{
id:3,
content:'工作好累'
}],
});
});
页面:
<h2>{{title}}</h2>
{{ each list as item}}
<p>id:{{item.id}},内容:{{item.content}}</p>
{{ /each }}
(4)循环渲染结合条件渲染:
router.get('/post',function(req,res){
res.render('post',{
title:'德云IT学院',
list:[{
id:1,
content:'今天天气不错'
},{
id:2,
content:'昨天几点睡觉的?'
},{
id:3,
content:'工作好累'
}],
targetId:2
});
});
页面:
<h2>{{title}}</h2>
{{ each list as item}}
{{ if item.id === targetId}}
<p style="color:#f00">id:{{item.id}},内容:{{item.content}}</p>
{{ else }}
<p>id:{{item.id}},内容:{{item.content}}</p>
{{ /if }}
{{ /each }}
三、请求对象Request
req.params:一个数组,包含命过名的路由参数
<a href="http://localhost:8089/test/12/15">params</a>
后台:
router.get('/post/:id/:userid',function(req,res){
res.send(req.params)
});
req.query:get请求的查询字符串参数
req.body:post的请求体内容
req.cookies:一个对象,包含从客户端传递来的cookie信息
req.headers:一个对象,从客户端接到的请求抱头
req.path:请求路径,不包含协议,端口,查询字符串
req.host:主机名
req.xhr:boolean值,判断请求是否是ajax请求
req.protocol:用于标示协议http,https
req.url:path+查询字符串
四、响应对象Response
res.status(code):设置http状态码,express默认是200。可利用此函数返回404或者500页面,重定向的话用redirect()
res.send(options):向客户端发送响应数据,可以是一个对象(key-value)
res.render(视图名,数据):页面的文件名(不带扩展名),“数据”是向页面发送的数据
res.cookie(name,value,[options]):设置cookie值
res.clearCookie(name,[options]):清除cookie值
res.redirect([status],url):重定向浏览器,默认状态码:302
url是路由里面的路径而不是视图里面的路径
res.json([status],json):向客户端发送json数据及其可选的状态码
res.jsonp([status],jsonp)
res.send([status],body):向客户端发送响应及其状态吗
res.type(type):相当于res.set(‘Content-Type‘,‘type‘)
五、get请求:
一般在网站开发中,get都用作数据获取和查询,类似于数据库中的查询操作,当服务器解析前台资源后即传输相应内容;而查询字符串是在URL上进行的,形如:
http://localhost:8080/login?goods1=0001&goods2=0002
(1)GET 请求的特点:
- GET 请求可被缓存
- GET 请求保留在浏览器历史记录中
- GET 请求可被收藏为书签
- GET 请求不应在处理敏感数据时使用
- GET 请求有长度限制:
IE:对URL的最大限制为2083个字符,若超出这个数字,提交按钮没有任何反应。
Firefox:对Firefox浏览器URL的长度限制为:65536个字符。
Safari:URL最大长度限制为80000个字符。
Opera:URL最大长度限制为190000个字符。
Google(chrome):URL最大长度限制为8182个字符。
- GET 请求只应当用于取回数据
(2)示例
在views下创建login.html文件
<form action="http://localhost:8082/login" method="get">
用户:
<input type="text" name="user" id="user" placeholder="用户名"/>
<br>
密码:
<input type="password" name="password" id="password" placeholder="密码"/>
<br>
<input type="submit" value="提交"/>
</form>
更改router下的index.js文件(路由文件)
var express = require('express');
var router = express.Router();
/* GET login page. */
router.get('/', function(req, res, next) {
res.render('login');
});
/* 获取登录页面的参数 */
router.get('/login',function(req,res){
console.log(req.query);
res.send("登录路由,user为:"+req.query.user+"==> password为:"+req.query.password)
})
module.exports = router;
六、post请求:
示例:
在views下创建post.html文件
<form action = "http://localhost:8082/add" method="POST">
用户:<input type="text" name = "userName">
<br><br>
密码:<input type="password" name = "userPwd">
<br><br>
<button type="submit">提交</button>
</form>
配置router下的index.js文件(路由文件)
//获取post页面
router.get('/post',function(req,res,next){
res.render('post')
})
//获取post方式的请求参数
router.post('/add',(req,res)=>{
res.send("登录路由,user为:"+req.body.userName+"==> password为:"+req.body.userPwd)
})
附:每次更改路由文件都要重新启动项目才能生效,这样开发效率不高。可以安装nodemon工具,在更改路由后就不用重新启动项目了
1、安装nodemon工具
npm install -g nodemon
2、修改项目根目录中的package.json文件
"scripts": {
"start": "node ./bin/www"
}
改为:
"scripts": {
"start": "nodemon ./bin/www"
}