Express提供的大部分功能都是通过中间件函数完成,这些中间件函数在Node.js收到 请求的时点 和 发送响应的时点 执行
connect模块提供了中间件框剪
方便在全局或路径级别或为单个路由插入中间件功能
(处理POST请求,提供静态文件服务,实现会话,cookie和身份验证)
1.了解中间件
允许在 接收到请求的时点 及 真正处理请求和发送响应的时点 之间附加功能。
可以用用身份验证,cookie和会话
提供了connect提供的底层中间件支持。
static:允许express服务器以流式处理静态文件的GET请求。express.static()
express-logger:实现格式化的请求记录器跟踪对服务器的请求
basic-auth-connect:提供对基本http身份验证的支持
cookie-parser:从请求读取cookie并在响应中设置cookie
cookie-session:提供基于cookie的会话支持
express-session:提供了会话实现
body-parser:把post请求正文中的JSON数据解析为req.body属性
compression:发给客户端的大响应提供Gzip压缩支持
csurf:提供跨站点请求伪造保护
1.1.全局范围把中间件分配给某个路由:
对所有路由指定中间件 user([path],middleware)(每个中间件组件都有构造函数,返回相应的中间件功能)
var express=require("express"); var bodyParser=require("body-parser"); var app=express(); app.user('/',bodyParser());
通过把一个 单独的路由 放在path参数 后来对其应用body-parser中间件
var express=require('express'); var bodyParser=require('body-parser'); var app=express(); app.get('/parserdRoute',bodyParser(),function(req,res){ res.send('this request was logged'); }) app.get('/otherRoute',function(req,res){ res.send('this request was not logged'); })
添加多个中间件函数
根据需要在全局范围和路由上分配任意多的中间件函数。
var express=require('express'); var bodyParser=require('body-parser'); var cookieParser=require('cookie-parser'); var session=require('cexpression-session'); var app=express(); app.use('/',bodyParser()). use('/',cookieParser()). use('/',session());
query中间件:将一个查询字符串从URL转换为JavaScript对象,将其保存为Request对象的query属性。
var express=require('express'); var app=express(); app.get('/',function(req,res){ var id=req.query.score; console.log(JSON.stringify(req.query)); res.send("done"); })
1.3.提供静态服务
static常用中间件
(可以使用让你直接从磁盘对客户端提供静态文件服务)
static中间件支持不会改变的 javascript,css,images,html
express.static(path,[options])
var express=require("express"); var app=express(); app.use('/',express.static('./')); app.use('/images',express.static('../images')); app.listen(8081);
1.4.处理POST正文数据
请求正文的数据可以是各种格式,如POST参数字符串,JSON字符串,或者原始数据。
express的中间件body-parser中间件解析请求中的正文JSON数据,格式化为Request对象的req.body属性
使用body-parser中间件处理在请求正文中的POST参数
(注意:app.use(body-parser())新版node已经废除)
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));//代替
var express=require('express'); var bodyParser=require('body-parser'); var app=express(); // app.use(bodyParser()); //这个已经过时了 app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.get('/',function(req,res){ var response='<form method="POST">'+ 'First:<input type="text" name="first"><br>'+ 'Last:<input type="text" name="last"><br>'+ '<input type="submit" value="Submit"></form>'; res.send(response); }) app.post('/',function(req,res){ console.log('111'); var response='<form method="POST">'+ 'First:<input type="text" name="first"><br>'+ 'Last:<input type="text" name="last"><br>'+ '<input type="submit" value="Submit"></form>'+ '<h1>Hello'+req.body.first+'</h1>' res.type('html'); res.send(response); console.log(req.body) }) app.listen(8082);
1.5.发送和接受cookie
express提供的cookie-parser中间件使得处理cookie很简单。
cookie-parser中间件从一个请求解析cookie,并作为JavaScript对象存储在req.cookies属性中。
res.cookie(name,value,[options])
var express=require('express'); var cookieParser=require('cookie-parser'); var app=express(); app.use(cookieParser()); app.get('/',function(req,res){ console.log(req.cookies); if(!req.cookies.hasVisited){ res.cookie('hasVisited','1',{ maxAge:60*60*1000, httpOnly:true, path:'/' }); } res.send("sending cookie"); }) app.listen(8081);
1.6.实现会话
res.cookie()
cookie-seesion被实现时,会被存储为req.session对象。对req.session的修改会跨越来自同一个浏览器的多个请求流动
var express=require('express'); var cookieParser=require('cookie-parser'); var cookieSession=require('cookie-session'); var app=express(); app.use(cookieParser()); app.use(cookieSession({secret:'MAGICALEXPRESSKEY'})); app.get('/library',function(req,res){ console.log(req.cookies); if(req.session.restricted){ res.send('You have been in the restricted section'+ req.session.restrictedCount+' times'); }else{ res.send('Welcome to the library'); } }); app.get('/restricted',function(req,res){ req.session.restricted=true; console.log("res="+req.session.restrictedCount); if(!req.session.restrictedCount){ req.session.restrictedCount=1; }else{ req.session.restrictedCount+=1; } res.redirect('/library'); }) app.listen(8081);
1.7.应用基本的HTTP身份验证
HTTP的身份验证使用Authorization标头从浏览器向服务器发送编码后的用户名和密码。
在浏览器中没有储存URL授权信息,浏览器会启动基本的登录对话框,输入用户名和密码。
基本的HTTP身份验证适合需要最低限度验证方法的基本网站。
var basicAuth=require('basic-auth-connect'); express.basicAuth(function(user,pass){})
var express=require('express'); var basicAuth=require('basic-auth-connect'); var app=express(); var auth=basicAuth(function(user,pass){ return(user=='weizai'&&pass=='test'); }) app.get('/library',function(req,res){ res.send('welcome to the library'); }) app.get('/restricted',auth,function(req,res){ res.send('welcome to the restricted section') }); app.listen(8081);
1.8.实现会话身份验证
基本的HTTP身份验证的主要缺点:证书被存储,登录会一直存在。不安全
更好的方法:实现自己的身份登录验证机制,将其储存在可以随意使之过期的会话中。
express内的session中间件对于实现会话的验证效果很好。session中间件附件一个session对象res.session对象上的调用方法
方法 | 说明 |
regenerate([callback]) | 移除并创建一个词新的req.session对象,让你重置会话 |
destroy([callback]) | 移除req.session对象 |
save([callback]) | 保存会话数据 |
touch([callback]) | 为会话重置maxAge计数 |
cookie | 指定把绘画链接到浏览器的cookie对象 |